繁体   English   中英

SQL更新执行顺序很重要?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM