SQL UPDATE评估顺序

时间:2010-02-04 21:03:27

标签: sql sql-update evaluation operator-precedence

以下查询中的评估顺序是什么:

UPDATE tbl SET q = q + 1, p = q;

也就是说,"tbl"."p"会设置为q还是q + 1?此处的评估顺序是否由SQL标准管理?

感谢。

更新

在考虑Migs' answer之后,我对我能找到的所有数据库进行了一些测试。虽然我不知道标准是什么,但实施方式各不相同。

鉴于

CREATE TABLE tbl (p INT NOT NULL, q INT NOT NULL);
INSERT INTO tbl VALUES (1, 5);   -- p := 1, q := 5
UPDATE tbl SET q = q + 1, p = q;

我发现"p""q"的值为:

database           p   q
-----------------+---+---
Firebird 2.1.3   | 6 | 6  -- But see "Update 2" below
InterBase 2009   | 5 | 6
MySQL 5.0.77     | 6 | 6  -- See "Update 3" below
Oracle XE (10g)  | 5 | 6
PostgreSQL 8.4.2 | 5 | 6
SQLite 3.3.6     | 5 | 6
SQL Server 2016  | 5 | 6

更新2

Firebird 2.5改变了它的行为以匹配我测试的大多数其他SQL引擎,只留下了MySQL。相关的发行说明条目"Logic Change in SET Clause"强烈建议 根据SQL规范 的大多数行为是正确的。

我已经窃听MySQL以评论这种行为(错误编号52861),因为它们似乎是异常值。

更新3

上述错误今天(2010-05-19)已关闭,文档集已更新,以便在 UPDATE 描述和与标准的差异中显式显示此行为SQL 部分。

Bravo,MySQL。

3 个答案:

答案 0 :(得分:13)

MySQL做“从左到右”评估并“看到”新值。 (在5.0.45-community-nt-log MySQL社区版上测试)

此外,从MySQL手册:“单表UPDATE分配通常从左到右进行评估。对于多表更新,无法保证按任何特定顺序执行分配。”

现在,鉴于评估顺序很重要,“一般”非常模糊,“不保证”非常糟糕。

所以,为了回答这个问题:IS是“SQL标准”指定的行为还是只是一种约定?


更新:掌握在“13.10 update statement:searching”项目中声明的SQL92规范“6”在更新任何T行之前,对T的每一行有效地计算(值表达式)。“

恕我直言并非绝对明确,但足以认为STANDARD不会“看到”您自己更新的结果。 考虑你的例子,Oracle,PostgreSQL和Interbase的方式。

答案 1 :(得分:6)

UPDATE没有看到其工作结果。

p将在更新前设置为q

以下代码将交换列:

DECLARE @test TABLE (p INT, q INT)

INSERT
INTO    @test
VALUES  (2, 3)

SELECT  *
FROM    @test

p    q
---  ---
  2    3

UPDATE  @test
SET     p = q,
        q = p

SELECT  *
FROM    @test

p    q
---  ---
  3    2

答案 2 :(得分:-1)

对表的写入必须在读取完成后正在进行的事务之后发生。