5

我在 SO 和 google 上都搜索过这些信息,但没有找到任何权威的答案。

当您有如下更新语句时:

UPDATE table SET rowA = rowB, rowB = NULL ...

看起来:

  • 排序不重要 ( UPDATE table SET rowB = NULL, rowA = rowB)
  • 尽管如此,结果是 rowA 获取 rowB 中的 prev 值,因为 UPDATE 似乎首先读取先前的值,然后更新它们。

我想知道上述两点对于 SQL 是否普遍适用,即它们是否是SQL UPDATE 语义的一部分,它们是否在标准中,或者它是否是一个实现细节(因此可能会发生变化)。谢谢!

编辑:让我强调我想要一个“权威”的答案;我已经对一些 SQL 实现进行了测试,这些行为确实是这里描述的行为。我需要的是一个“证明”,证明这实际上是在 SQL 标准/规范/UPDATE 的语义中,并带有指向该标准的链接,或者是一个代理可靠来源(MSDN、dev.mysql.com、Oracle 或 PostgreSQL文档,...)

4

3 回答 3

6

James R. Groff、Paul N. Weinberg:SQL The complete reference (Osborne 1999),第 209 页指出

开始报价

如果赋值列表中的表达式引用目标表的列之一,则用于计算表达式的值 是应用任何更新之前当前行中该列的值。WHERE 子句中出现的列引用也是如此。例如,考虑这个(有点做作的)UPDATE 语句:

UPDATE OFFICES
 SET QUOTA = 400000.00, SALES = QUOTA
WHERE QUOTA < 400000.00

更新前,比尔亚当斯的QUOTA身价为 350,000 美元,SALES身价为 367,911 美元。更新后,他的行的SALES价值是 350,000 美元,而不是 400,000 美元。因此 SET 子句中的赋值顺序无关紧要;可以按任何顺序指定分配。

结束报价

ANSI-92 SQL 标准 (X3H2-93-004) 草案的第 13.9 章第 6 项第 393 页支持相同,可在此处找到。

这是迄今为止最独立的实现,也是我能得到的最接近的。

X3H2-93-004 的其他来源可以在这里找到,例如(第 590 页,第 15 项)

于 2013-04-10T07:28:09.997 回答
1

这是标准行为。当您引用一行时,您指的是更新前的版本。

output在 SQL Server 中,可以使用子句将两个行版本可视化

update  YourTable
set     col1 = col1 + 1
output  deleted.col1   -- Pre-update version of row
,       inserted.col1  -- Post-update version of row
于 2013-04-02T09:40:01.497 回答
0

update来自(http://www.postgresql.org/docs/8.3/static/sql-update.html)的postgeSQL文档

表达式
要分配给列的表达式。表达式可以使用表中此列和其他列的旧值。

于 2013-04-05T13:29:24.660 回答