【问题标题】:Mysql Copy And Update In Same StatementMysql 在同一语句中复制和更新
【发布时间】:2013-04-24 13:51:58
【问题描述】:

我知道这行得通,但这是一种好的做法吗?

update test set field1=field1+field2, field2=0;

在将值添加到 field1 总数之前,我不希望将 field2 设置为 0。这会一直按计划进行吗?

【问题讨论】:

  • 我认为它没有理由不工作,因为语句的 set 部分是从左到右评估的......但为了确定,我会将它分成两部分 @ 987654326@ 语句并尽可能将它们放入事务中(仅在两次更新都成功后提交)
  • 这将按预期工作-假设我没看错的话。您可能需要添加 WHERE field2 != 0,这样它就不会擦除任何以前修改过的条目。

标签: mysql


【解决方案1】:

如果 MySQL 遵循标准,它应该可以工作。但在这种情况下,它没有(遵循标准)。笔记。在标准的 ISO?ANSI SQL 中,这些语句是等效的,并且在表中产生相同的更改。 (任何人都可以在 SQL-Server 或 Oracle 中尝试它们。我认为第 3 种变体仅适用于 Postgres):

UPDATE test 
SET field1 = field1 + field2, field2 = 0 ;

UPDATE test 
SET field2 = 0, field1 = field1 + field2 ;

UPDATE test 
SET (field1, field2) = (field1 + field2, 0) ;

因此,在 MySQL 中,您的语句在大多数情况下都会像您预期的那样工作,正如 MySQL documentation 所述:

单表UPDATE 分配通常从左到右进行评估。对于多表更新,不能保证以任何特定顺序执行分配。

请注意“一般”。 100% 确定,您可以在 2 个语句中进行更新(在事务中):

UPDATE test 
SET field1 = field1 + field2 ;

UPDATE test 
SET field2 = 0 ;

或使用临时表。

【讨论】:

  • @eggyal: 不,按照标准,field2 之前的值将用于field1+field2 计算,然后才会应用0。
【解决方案2】:

在手册中找到(http://dev.mysql.com/doc/refman/5.0/en/update.html):

UPDATE t1 SET col1 = col1 + 1, col2 = col1;

单表 UPDATE 赋值一般是从左到右求值的 正确的。对于多表更新,不能保证 作业按任何特定顺序执行。

所以它总是有效的

【讨论】:

  • “一般”不是“总是”的同义词
猜你喜欢
  • 2014-07-22
  • 2018-04-18
  • 2021-03-29
  • 1970-01-01
  • 1970-01-01
  • 2010-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多