MySQL,用一个查询更新多个表
我有一个更新三个表的函数,但我使用三个查询来执行此操作。我希望使用更方便的方法来进行良好的实践。
如何使用单个查询更新 MySQL 中的多个表?
I have a function that updates three tables, but I use three queries to perform this. I wish to use a more convenient approach for good practice.
How can I update multiple tables in MySQL with a single query?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
以两个表为例:
Books
和Orders
。如果我们在Orders
表中使用Order.ID = 1002
增加特定订单中的图书数量,那么我们还需要减少我们的库存在Books
表中具有相同的编号。Take the case of two tables,
Books
andOrders
. In case, we increase the number of books in a particular order withOrder.ID = 1002
inOrders
table then we also need to reduce that the total number of books available in our stock by the same number inBooks
table.要查看要更新的内容,您可以将其转换为选择语句,例如:
使用与其他答案相同的表的示例:
编辑:
只是为了好玩,让我们添加一些更有趣的内容。
假设您有一个
书籍
表和一个作者
表。您的图书
有一个author_id
。但最初创建数据库时,没有设置外键约束,后来前端代码的一个错误导致一些书籍添加了无效的author_id
。作为 DBA,您不想通过所有这些书籍
来检查author_id
应该是什么,因此决定数据捕获器将修复books
指向正确的作者
。但是书籍太多,无法逐一浏览,假设您知道那些具有与实际author
相对应的author_id
的书籍是正确的。只有author_id
不存在的那些才是无效的。已经有一个接口供用户更新书籍详细信息,并且开发人员不想仅仅因为这个问题而更改该接口。但现有的接口会进行INNER JOIN Authors
,因此所有具有无效作者的书籍都被排除在外。你可以做的是:插入一个假作者记录,如“未知作者”。然后更新所有不良记录的
author_id
以指向未知作者。然后数据捕获器可以搜索作者设置为“未知作者”的所有书籍,查找正确的作者并修复它们。如何更新所有不良记录以指向未知作者?像这样(假设未知作者的
author_id
为 99999):以上还将更新具有
NULL
author_id
的books
> 致未知作者。如果您不希望这样,当然可以添加AND books.author_id IS NOT NULL
。To see what this is going to update, you can convert this into a select statement, e.g.:
An example using the same tables as the other answer:
EDIT:
Just for fun, let's add something a bit more interesting.
Let's say you have a table of
books
and a table ofauthors
. Yourbooks
have anauthor_id
. But when the database was originally created, no foreign key constraints were set up and later a bug in the front-end code caused some books to be added with invalidauthor_id
s. As a DBA you don't want to have to go through all of thesebooks
to check what theauthor_id
should be, so the decision is made that the data capturers will fix thebooks
to point to the rightauthors
. But there are too many books to go through each one and let's say you know that the ones that have anauthor_id
that corresponds with an actualauthor
are correct. It's just the ones that have nonexistentauthor_id
s that are invalid. There is already an interface for the users to update the book details and the developers don't want to change that just for this problem. But the existing interface does anINNER JOIN authors
, so all of the books with invalid authors are excluded.What you can do is this: Insert a fake author record like "Unknown author". Then update the
author_id
of all the bad records to point to the Unknown author. Then the data capturers can search for all books with the author set to "Unknown author", look up the correct author and fix them.How do you update all of the bad records to point to the Unknown author? Like this (assuming the Unknown author's
author_id
is 99999):The above will also update
books
that have aNULL
author_id
to the Unknown author. If you don't want that, of course you can addAND books.author_id IS NOT NULL
.您也可以使用像这样的联接来通过一个查询来完成此操作:
当然,然后只需发送这个查询。您可以在此处阅读有关联接的更多信息: http://dev.mysql.com /doc/refman/5.0/en/join.html。对于多个表更新的排序和限制还有一些限制,您可以在此处阅读:http://dev.mysql.com/doc/refman/5.0/en/update.html(只需 ctrl+f“加入”)。
You can also do this with one query too using a join like so:
And then just send this one query, of course. You can read more about joins here: http://dev.mysql.com/doc/refman/5.0/en/join.html. There's also a couple restrictions for ordering and limiting on multiple table updates you can read about here: http://dev.mysql.com/doc/refman/5.0/en/update.html (just ctrl+f "join").
这通常就是存储过程的用途:按顺序执行多个 SQL 语句。使用回滚,您可以确保将它们视为一个工作单元,即它们要么全部执行,要么都不执行,以保持数据一致。
That's usually what stored procedures are for: to implement several SQL statements in a sequence. Using rollbacks, you can ensure that they are treated as one unit of work, ie either they are all executed or none of them are, to keep data consistent.
当您说多个查询时,您的意思是多个 SQL 语句,如:
或多个查询函数调用,如:
前者都可以使用单个 mySqlQuery 调用来完成,如果这是您想要实现的,只需调用下面的 mySqlQuery 函数方式:
这将通过一次 mySqlQuery() 调用执行所有三个查询。
When you say multiple queries do you mean multiple SQL statements as in:
Or multiple query function calls as in:
The former can all be done using a single mySqlQuery call if that is what you wanted to achieve, simply call the mySqlQuery function in the following manner:
This will execute all three queries with one mySqlQuery() call.
假设我有
Table1
,其中包含主键_id
和布尔列doc_availability
;Table2
具有外键_id
和 DateTime 列last_update
,我想更改_id
14 文档的可用性将Table1
中的值设置为 0,即不可用,并使用文档上次更新时的时间戳更新Table2
。以下查询将完成该任务:Let's say I have
Table1
with primary key_id
and a boolean columndoc_availability
;Table2
with foreign key_id
and DateTime columnlast_update
and I want to change the availability of a document with_id
14 inTable1
to 0 i.e unavailable and updateTable2
with the timestamp when the document was last updated. The following query would do the task:'更新产品、类别、子类别设置category.name=?,subcategoey.name=?, products.name=?, products.price=?, products.available_qty=? WHERE Category.id= subcategoey.cid AND subcategoey.id = products.scid AND products.id=?',[catname,scatname,pname,price,available_qty,id],
它对我有用...
'UPDATE products,category,subcategoey set category.name=?,subcategoey.name=?, products.name=?, products.price=?, products.available_qty=? WHERE category.id= subcategoey.cid AND subcategoey.id = products.scid AND products.id=?',[catname,scatname,pname,price,available_qty,id],
it works for me...
问题已经得到解答,但还有一件事需要注意。
JOIN
查询必须位于SET
查询之前这将起作用
这将不起作用
The question is already answered but there is one thing to take care of.
The
JOIN
query must be before theSET
queryThis will work
This will NOT work