我遇到一个包含多个更新语句的CTE表达式的奇怪问题。
我可以使用以下SQL复制:-
DROP TABLE IF EXISTS foo;
DROP TABLE IF EXISTS baa;
CREATE TABLE foo(id BIGSERIAL, attributes JSONB);
CREATE TABLE baa(id BIGSERIAL, attributes JSON );
INSERT INTO foo(attributes) SELECT jsonb_build_object('foo', 'baa');
WITH STEP_ONE AS (
UPDATE foo
SET attributes = attributes ||jsonb_build_object('foo2', 'baa2')
WHERE id = 1
RETURNING attributes->>'foo' AS foo_att,id
), STEP_TWO AS (
INSERT INTO baa(attributes)
SELECT json_build_object('foo', id)
FROM STEP_ONE
RETURNING id as baa_id
)
UPDATE foo
SET attributes = attributes ||jsonb_build_object('baa', baa_id)
FROM STEP_TWO
WHERE id = 1
这不会更新表foo。但是用“ SELECT * FROM STEP_TWO”替换最终更新将显示记录。
这是Postgresql中的错误吗?还是我在文档中缺少有关在CTE中多次更新单个表的内容?
Postgres版本:
PostgreSQL 11.4 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.3 20140911 (Red Hat 4.8.3-9), 64-bit
答案 0 :(得分:4)
是的,这个is documented:
所有语句都使用相同的 snapshot 执行(请参见Chapter 13),因此它们无法“看到”彼此对目标表的影响。
您将不得不重写查询,以便每个表在该语句中仅被修改一次,或者您必须运行两个单独的语句。