只是感兴趣,为什么下面(简化)示例以这种方式工作。
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
事务隔离=读取提交
谢谢!
答案 0 :(得分:13)
我怀疑它与docs -
中的这一行有关主要查询和WITH查询都是(名义上)执行的 同时。这意味着数据修改的效果 其他语句中的语句无法从查询的其他部分看到 而不是通过读取它的RETURNING输出。如果两个这样的数据修改 语句尝试修改同一行,结果是 未指定的。
虽然我认为ID可用,因为它在WITH子查询中没有变化,但可能会出现行可见性。 “未指定”一词非常模糊,这可能是postgres列表中的一个问题,因此其中一位大师可以对其进行破解......
编辑:为了提供更多信息,我还尝试将DELETE
替换为SELECT *
,这会返回预期的行。我的直接反应是,如果它能找到返回它们的行,它应该能够找到它们来删除它们。但是如果我考虑更多,这个测试支持引用,因为数据修改语句与非数据修改语句配对产生预期结果,而两个数据修改语句产生意外结果。