[英]SQL update execution order matters?
我一直认为在SQL UPDATE
期间,现有值将保持不变,直到整个更新语句完成,但我在实践中看到不同的行为。
Inventory
-----------------------------
date base flexible
2014-05-01 5 10
2014-05-02 5 10
UPDATE Inventory SET base = GREATEST(0, base - 7), flexible = flexible - GREATEST(0, (7 - base)) WHERE date = '2014-05-01'
UPDATE Inventory SET flexible = flexible - GREATEST(0, (7 - base)), base = GREATEST(0, base - 7) WHERE date = '2014-05-02'
Inventory
-----------------------------
date base flexible
2014-05-01 0 3
2014-05-02 0 8
在第一个示例中,似乎使用第一个表达式将base
更新为零,导致第二个表达式不正确地计算(7 - 0)
而不是(7 - 5)
。
谁能解释一下这里发生了什么?
MySQL打破了标准;
它使用当前字段值更新列,考虑更新中的字段顺序,而不是遵循使用更新语句之前的字段值的SQL标准。
来自文档 ;
如果从表中访问要在表达式中更新的列,UPDATE将使用列的当前值。 以下语句中的第二个赋值将col2设置为当前(更新的)col1值,而不是原始col1值。 结果是col1和col2具有相同的值。 此行为与标准SQL不同。
UPDATE t1 SET col1 = col1 + 1,col2 = col1;
您将在提交之前看到自己的更改,而其他人则不会。
看看这个 。 我认为这是因为GREATEST功能......
如何将base
值存储在用户变量中,如下所示:
UPDATE Inventory
SET base = (@base := base), flexible = (@flexible := flexible),
base = GREATEST(0, @base - 7),
flexible = @flexible - GREATEST(0, (7 - @base));
这是测试:
mysql> insert into Inventory values('2014-05-01', 5, 10);
Query OK, 1 row affected (0.00 sec)
mysql> insert into Inventory values('2014-05-02', 5, 10);
Query OK, 1 row affected (0.00 sec)
mysql>
mysql> UPDATE Inventory
-> SET base = (@base := base), flexible = (@flexible := flexible),
-> base = GREATEST(0, @base - 7),
-> flexible = @flexible - GREATEST(0, (7 - @base));
Query OK, 2 rows affected (0.00 sec)
Rows matched: 2 Changed: 2 Warnings: 0
mysql> SELECT * FROM Inventory;
+------------+------+----------+
| date | base | flexible |
+------------+------+----------+
| 2014-05-01 | 0 | 8 |
| 2014-05-02 | 0 | 8 |
+------------+------+----------+
2 rows in set (0.00 sec)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.