考虑此UPDATE语句:
UPDATE tbl_book
SET return_date = planned_return_date,
planned_return_date = null
WHERE book_id = 12;
我想此更新的工作方式如下:
我的假设正确吗? SET-Clauses的顺序重要吗? 我什至猜测,分配中的列引用将始终反映“旧”记录的值,对吗?在这种情况下,排序无所谓...
编辑2018-11-08:为了澄清,我用mysql和postgresql标记了我的查询,因为我需要知道两者的答案。
答案 0 :(得分:4)
根据SQL标准,不应在任何这些表达式中使用更新后的值。 2003规范 1 中的相关文本指出:
在更新T的任何行之前,已针对T的每一行有效地评估了每个
<update source>
的{{1}}。
<set clause>
子句中<update source>
子句中每个赋值运算符右边的部分。
似乎MySQL可能未遵循此处的标准,但我相信PostgreSQL和大多数其他数据库产品会遵循。对于MySQL,这是documented:
以下语句中的第二个赋值将
SET
设置为当前(更新)的col2
值,而不是原始的col1
值。结果是col1
和col1
具有相同的值。 此行为不同于标准SQL。col2
(我的重点)
1 第14.11节UPDATE t1 SET col1 = col1 + 1, col2 = col1;
。 2003标准的选择是任意的,我不认为这在标准的版本之间会有太大变化。
答案 1 :(得分:3)
您的查询是:
UPDATE tbl_book
SET return_date = planned_return_date,
planned_return_date = null
WHERE book_id = 12;
进行update
时,请将该表视为每个记录有两个版本-我们将其称为“旧”和“新”,因为这是触发器中常用的术语。
new 记录中的值为set
。 =
另一侧的值来自 old 记录。
答案 2 :(得分:2)
SET-Clauses的顺序重要吗?是的,顺序是一个问题(对于mysql),这是因为如果您在下面的查询中执行
create table t
(
id int, id1 int, id2 int
);
insert into t
values
(1,2,3),
(1,2,4);
select * from t;
update t
set id2=null,
id1=id2
where id1=2;
select * from t
输出将为
id id1 id2
1 null null
1 null null
但是如果您这样做,那么输出结果将低于
update t
set
id1=id2,
id2=null
id id1 id2
1 3 null
1 4 null
顺序是set子句中的问题