更新查询 (Postgres) 中 Set 子句的执行顺序

Din*_*mar 4 postgresql update sql-standard

我最近在 Postgres 中遇到了这种奇怪的行为。我有一张像下面这样的表:

sasdb=# \d emp_manager_rel 
           表“db3004db.emp_manager_rel”
   专栏 | 类型 | 整理 | 可空 | 默认
------------+--------+-----------+------------+----- ----
 emp_id | bigint | | |
 manager_id | bigint | | |

select * from emp_manager_rel ;
 emp_id | manager_id
--------+------------
      1 | 123

我执行了以下更新语句:

更新1:

更新 emp_manager_rel 设置 manager_id = manager_id+emp_id , emp_id=emp_id*4;

更新表格如下:

emp_id | manager_id
--------+------------
      4 | 124

更新 2:我执行了以下查询(在原始表上,而不是在更新表上)

更新 emp_manager_rel 设置 emp_id=emp_id*4 , manager_id = manager_id+emp_id ;

它更新表格如下:

emp_id | manager_id
--------+------------
      4 | 124

我期望 UPDATE 2 上 manager_id 的值为 127(因为 emp_id 已被 empid * 4 更改为 4)。但是,两个 UPDATES 产生相同的结果。我想知道 ANSI 标准中 set 子句的执行顺序是什么。

a_h*_*ame 9

这种行为并没有什么“奇怪”之处——这是处理此类更新的唯一明智方法。

没有“更新顺序”这样的东西——所有 SET 子句都应该被假定为并行发生。

SQL 标准要求赋值的右侧是列的值,就像在 UPDATE 语句开始之前一样。列分配在 UPDATE 语句中列出的顺序与 UPDATE 语句的结果无关。

UPDATE 语句的任何其他行为都将是错误并违反 SQL 标准。

出于同样的原因,以下语句将交换两列值:

update some_table
   set x = y, y = x;
Run Code Online (Sandbox Code Playgroud)

或者

update some_table
   set y = x, x = y;
Run Code Online (Sandbox Code Playgroud)

  • @DineshKumar SQL 语句被设计为原子的。多说几句就行了。 (2认同)