简体   繁体   English

SQL UPDATE评估顺序

[英]SQL UPDATE order of evaluation

What is the order of evaluation in the following query: 以下查询中的评估顺序是什么:

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

That is, will "tbl"."p" be set to q or q + 1 ? 也就是说, "tbl"."p"会设置为q还是q + 1 Is order of evaluation here governed by SQL standard? 此处的评估顺序是否受SQL标准的约束?

Thanks. 谢谢。

UPDATE UPDATE

After considering Migs' answer , I ran some tests on all DBs I could find. 在考虑了Migs的回答之后 ,我对我能找到的所有数据库进行了一些测试。 While I don't know what the standard says, implementations vary. 虽然我不知道标准是什么,但实施方式各不相同。

Given 特定

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;

I found the values of "p" and "q" were: 我发现"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

UPDATE 2 更新2

Firebird 2.5 changes its behavior to match the majority of other SQL engines I tested, leaving MySQL alone. Firebird 2.5改变了它的行为,以匹配我测试的大多数其他SQL引擎,只留下MySQL。 The relevant Release Notes entry, "Logic Change in SET Clause" , strongly suggests that the majority behavior is correct per SQL specifications . 相关的发行说明条目“SET子句中的逻辑更改”强烈建议每个SQL规范的大多数行为都是正确的

I've bugged MySQL to comment on this behavior (bug no. 52861 ), as they seem to be the outlier. 我已经窃听MySQL以评论这种行为(错误号52861 ),因为它们似乎是异常值。

UPDATE 3 更新3

The aforementioned bug is today (2010-05-19) closed, and the documentation set to be updated to make this behavior explicit both in the UPDATE description and in the Differences from Standard SQL section. 上述错误今天(2010-05-19)已关闭,并且文档集已更新,以使此行为在UPDATE描述和与标准SQL差异部分中都是显式的。

Bravo, MySQL. Bravo,MySQL。

MySQL does "left to right" evaluation and does "see" the new values. MySQL做“从左到右”评估,并“看到”新值。 (Tested on 5.0.45-community-nt-log MySQL Community Edition) (在5.0.45-community-nt-log MySQL社区版上测试)

Furthermore, from the MySQL manual: "Single-table UPDATE assignments are generally evaluated from left to right. For multiple-table updates, there is no guarantee that assignments are carried out in any particular order." 此外,从MySQL手册:“单表UPDATE分配通常从左到右进行评估。对于多表更新,无法保证按任何特定顺序执行分配。”

Now, "generally" is quite vague and "no guarantee" is very bad given that the order of evaluation is important. 现在,鉴于评估的顺序很重要,“一般”是相当模糊的,“不保证”是非常糟糕的。

So, in order to answer the question: IS the behaviour specified by "the SQL standard" or is it just a convention? 所以,为了回答这个问题:IS是“SQL标准”指定的行为还是只是一种约定?


UPDATE: Got hold of the SQL92 specs which state at "13.10 update statement: searched" item "6) The (value expression)s are effectively evaluated for each row of T before updating any row of T." 更新:掌握在“13.10 update statement:searching”项目“6”中声明的SQL92规范。在更新T的任何行之前,对T的每一行有效地计算(值表达式)s。“

IMHO not absolutely unambiguous, but enough to consider that the STANDARD is NOT to "see" the results of your own update. 恕我直言并非绝对明确,但足以认为标准不是“看到”你自己更新的结果。 Considering your example, the way Oracle, PostgreSQL and Interbase do it. 考虑您的示例,Oracle,PostgreSQL和Interbase的方式。

The UPDATE does not see the results of its work. UPDATE没有看到其工作的结果。

p will be set to q as of before update. p将在更新前设置为q

The following code will just swap the columns: 以下代码将只交换列:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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