在CTE中先前插入的UPDATE行

时间:2017-10-20 14:58:46

标签: sql postgresql common-table-expression

是否可以更新先前在CTE中插入的值,或者在更新值之前是否必须首先提交整个事务?

我有这种“循环依赖”,其中B需要来自A的ID,但如果other_table中符合某个条件,那么A应该是使用id中生成的B进行了更新。

我尝试了以下操作,但我尝试A的{​​{1}}字段似乎无法正确更新(UPDATE)。查询的其余部分按预期工作。

测试数据:

UPDATE 0

CREATE TABLE table_a ( a_id serial, col_a text, column_to_update text ) ; CREATE TABLE table_b ( b_id serial, a_id int, other_table_id int ) ; CREATE TABLE other_table ( other_table_id int, condition_col bool ) ; INSERT INTO other_table (other_table_id, condition_col) VALUES (1, FALSE), (2, TRUE) ; + INSERT声明:

UPDATE

根据@ laurenz-albe

解决问题
WITH insert_a_query AS (
     INSERT INTO table_a (col_a) VALUES ('hello')
     RETURNING a_id
),

insert_b_query AS (
     INSERT INTO table_b (other_table_id, a_id)
     SELECT other_table_id, (SELECT a_id FROM insert_a_query)
     FROM other_table
     RETURNING other_table_id, b_id
)

UPDATE table_a
SET column_to_update = b_id
FROM other_table
LEFT JOIN insert_b_query ON other_table.other_table_id = insert_b_query.other_table_id
WHERE other_table.condition_col = TRUE
AND table_a.a_id = (SELECT a_id FROM insert_a_query)

1 个答案:

答案 0 :(得分:1)

这不起作用,例如the documentation说:

  

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

解决方法是在第一个CTE中显式调用相关序列上的nextval函数,然后执行两个INSERT