MySQL UPDATE两个表的结果不符合预期(查询执行的顺序是什么?)

时间:2013-08-14 06:57:35

标签: mysql

第一张表18_6_TransactionPartners

CompanyName | RegistrationNumber | PreviousCompanyName
----------------------------------------------------------
  tests5555 |  x                 |   tests444

第二张表2_1_journal

专栏

 TransactionPartnerName
 -------------------------
        tests444

尝试使用CompanyName = tests111的变量更新两个表,其中RegistrationNumber的变量为x

查询

UPDATE

18_6_TransactionPartners , 2_1_journal

SET

18_6_TransactionPartners.PreviousCompanyName=IF(18_6_TransactionPartners.RegistrationNumber = ?, 18_6_TransactionPartners.CompanyName, 18_6_TransactionPartners.PreviousCompanyName),

18_6_TransactionPartners.CompanyName=IF(18_6_TransactionPartners.RegistrationNumber = ?, ?, 18_6_TransactionPartners.CompanyName),

2_1_journal.TransactionPartnerName=IF(2_1_journal.TransactionPartnerName = 18_6_TransactionPartners.PreviousCompanyName, 18_6_TransactionPartners.CompanyName, 2_1_journal.TransactionPartnerName)

结果得到

第一张表18_6_TransactionPartners

CompanyName | RegistrationNumber | PreviousCompanyName
----------------------------------------------------------
  tests111 |  x                 |   tests5555 

18_6_TransactionPartners一切正常(没有问题;表格仅显示情况)

但是第二张表2_1_journal得到了

专栏

 TransactionPartnerName
 -------------------------
        tests555

但预计会获得tests111

查询2_1_journal.TransactionPartnerName=IF(2_1_journal.TransactionPartnerName = 18_6_TransactionPartners.PreviousCompanyName, 18_6_TransactionPartners.CompanyName, 2_1_journal.TransactionPartnerName)出了什么问题?

假设,查询首先必须将值从CompanyName复制到PreviousCompanyName。然后在CompanyName中插入新值。然后插入TransactionPartnerName

但不是。从我的意见而不是CompanyName值,它会插入PreviousCompanyName值。或者首先在表2_1_journal中插入?

请建议正确的查询

3 个答案:

答案 0 :(得分:1)

这是预期的行为。每当引用update子句中的字段时,这些字段的值将是更新前的值。所以在你的情况下,最后一个更新子句

2_1_journal.TransactionPartnerName=IF(2_1_journal.TransactionPartnerName = 18_6_TransactionPartners.PreviousCompanyName, 18_6_TransactionPartners.CompanyName, 2_1_journal.TransactionPartnerName)

将获得更新之前18_6_TransactionPartners.CompanyName的值,因此tests111。

作为快速修复,您需要在子句中传递新值以获得所需的结果:

2_1_journal.TransactionPartnerName=IF(2_1_journal.TransactionPartnerName = 18_6_TransactionPartners.PreviousCompanyName, ?, 2_1_journal.TransactionPartnerName)

您真正想要的是使用transactions(如果使用InnoDB引擎):

BEGIN;
SELECT PreviousCompanyName FROM 18_6_TransactionPartners WHERE RegistrationNumber = ? FOR UPDATE; //plug in 'x' and save the value of PreviousCompanyName
UPDATE 18_6_TransactionPartners SET PreviousCompanyName = CompanyName, CompanyName = ? WHERE RegistrationNumber = ?; //plug in 'tests111' and 'x'
UPDATE 2_1_journal SET TransactionPartnerName = ? WHERE TransactionPartnerName = ?; //plug in 'test111' and your saved value of PreviousCompanyName
COMMIT;

或者,如果您总是想要更新2_1_journal表中的值,您可以这样做:

BEGIN;
UPDATE 18_6_TransactionPartners SET PreviousCompanyName = CompanyName, CompanyName = ? WHERE RegistrationNumber = ?; //plug in 'tests111' and 'x'
UPDATE 2_1_journal SET TransactionPartnerName = (SELECT CompanyName FROM 18_6_TransactionPartners WHERE RegistrationNumber = ?); //plug in 'x'
COMMIT;

答案 1 :(得分:0)

您是否必须在一个SQL语句中更新两个表。我不知道你甚至可以这样做 - 我会把它们分成不同的查询 - 也许这会让事情变得复杂。

答案 2 :(得分:0)

MySQL不保证将更改应用于多表更新语句中的各个表的顺序。要完成您想要的操作,您应该在事务中将此操作作为两个UPDATE语句执行。

BEGIN

更新2_1_Journal ...

更新18_6_TransactionPartners ...

COMMIT