PostgreSql - > CTE + UPDATE + DELETE - >不是预期的结果,为什么?

时间:2012-12-10 18:14:10

标签: postgresql common-table-expression

只是感兴趣,为什么下面(简化)示例以这种方式工作。

CREATE TABLE test (id SERIAL, val INT NOT NULL, PRIMARY KEY(id));
INSERT INTO test (val) VALUES (1);

WITH t AS ( UPDATE test SET val = 1 RETURNING id ) 
DELETE FROM test WHERE id IN ( SELECT id FROM t);

结果:
删除0

问题:
为什么DELETE没有找到要删除的行?

PostgreSql版本9.2.1
事务隔离=读取提交

谢谢!

1 个答案:

答案 0 :(得分:13)

我怀疑它与docs -

中的这一行有关
  

主要查询和WITH查询都是(名义上)执行的   同时。这意味着数据修改的效果   其他语句中的语句无法从查询的其他部分看到   而不是通过读取它的RETURNING输出。如果两个这样的数据修改   语句尝试修改同一行,结果是   未指定的。

虽然我认为ID可用,因为它在WITH子查询中没有变化,但可能会出现行可见性。 “未指定”一词非常模糊,这可能是postgres列表中的一个问题,因此其中一位大师可以对其进行破解......

编辑:为了提供更多信息,我还尝试将DELETE替换为SELECT *,这会返回预期的行。我的直接反应是,如果它能找到返回它们的行,它应该能够找到它们来删除它们。但是如果我考虑更多,这个测试支持引用,因为数据修改语句与非数据修改语句配对产生预期结果,而两个数据修改语句产生意外结果。