12

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

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
事务隔离 = 读已提交

谢谢!

4

1 回答 1

14

我怀疑它与文档中的这一行有关-

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

虽然我认为 ID 是可用的,因为它在 WITH 子查询中没有改变,但行可见性可能会发生一些事情。“未指定”一词非常模糊,这可能确实是 postgres 列表的一个问题,因此其中一位大师可以对此有所了解......

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

于 2012-12-10T18:36:39.613 回答