WITH first_insert AS
(
INSERT INTO first_insert_table (column_of_first_insert_table)
VALUES (10)
RETURNING first_insert_table_id
),
second_insert AS
(
INSERT INTO second_insert_table(column_of_second_insert_table)
VALUES((SELECT * FROM first_insert))
RETURNING second_insert_table_id
)
--here doesn't update column_of_first_insert_table!
UPDATE first_insert_table
SET column_of_first_insert_table = column_of_first_insert_table + 1
WHERE first_insert_table_id = (SELECT * FROM first_insert) ;
当我尝试更新column_of_first_insert_table
表时,为什么这个查询不更新first_insert_table
的first_insert_table
列?
它没有执行预期更新的原因与您的示例的简化版本不会显示在WITH
子句中插入的行的原因相同:
with cte as (
insert into first_insert_table (column_of_first_insert_table)
values (10)
)
select * from first_insert_table
执行上述语句时,INSERT
确实成功发生,但语句的SELECT
部分没有看到它,因为SELECT
只看到语句开始执行时存在的数据。
你的例子也是如此。 WHERE
的UPDATE
子句只能找到整个语句开始时存在的行,因此它不会看到插入WITH
子句中的行。
记录此行为(7.8.2. Data-Modifying Statements in WITH
):
WITH
中的子语句彼此同时并与主查询一起执行。因此,在WITH
中使用数据修改语句时,指定更新实际发生的顺序是不可预测的。所有语句都使用相同的快照执行(参见第13章),因此它们无法“看到”彼此对目标表的影响。这减轻了行更新的实际顺序的不可预测性的影响,并且意味着RETURNING
数据是在不同的WITH
子语句和主查询之间传递变化的唯一方式。