【问题标题】:UPDATE row inserted earlier in CTE之前在 CTE 中插入的 UPDATE 行
【发布时间】:2017-10-20 14:58:45
【问题描述】:

是否可以更新之前在 CTE 中插入的值,还是必须先提交整个事务才能更新该值?

我有这个“循环依赖”,其中B 需要来自A 的 id,但是如果在other_table 中满足某个条件,则应该使用生成的id 更新A B.

我尝试了以下操作,但我尝试对 UPDATE 尝试的 A 中的字段似乎没有正确更新 (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声明:

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)

根据@laurenz-albe 解决问题

WITH a_sequence AS (
    SELECT nextval('table_a_a_id_seq') AS a_id
),
insert_b_query AS (
     INSERT INTO table_b (other_table_id, a_id)
     SELECT other_table_id, (SELECT a_id FROM a_sequence)
     FROM other_table
     RETURNING other_table_id, b_id
)

INSERT INTO table_a (a_id, col_a, column_to_update)
SELECT
    (SELECT a_id FROM a_sequence)
    , 'hello'
    , b_id
FROM insert_b_query
LEFT JOIN other_table ON other_table.other_table_id = insert_b_query.other_table_id
WHERE other_table.condition_col = TRUE
;

【问题讨论】:

    标签: sql postgresql common-table-expression


    【解决方案1】:

    这行不通,就像the documentation 说的那样:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-12-18
      • 1970-01-01
      • 1970-01-01
      • 2018-09-03
      • 2014-07-23
      • 1970-01-01
      相关资源
      最近更新 更多