更新无法使用 with 子句
Update isn't working using with clause
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) ;
当我尝试更新 first_insert_table
table 时,为什么此查询不更新 first_insert_table
的 column_of_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
只看到语句开始执行时存在的数据。
您的示例中也发生了同样的情况。 UPDATE
的 WHERE
子句只能找到整个语句开始时存在的行,因此它看不到 WITH
子句中插入的行。
此行为已记录 (7.8.2. Data-Modifying Statements in WITH
):
The sub-statements in WITH
are executed concurrently with each other and with the main query. Therefore, when using data-modifying statements in WITH
, the order in which the specified updates actually happen is unpredictable. All the statements are executed with the same snapshot (see Chapter 13), so they cannot “see” one another's effects on the target tables. This alleviates the effects of the unpredictability of the actual order of row updates, and means that RETURNING
data is the only way to communicate changes between different WITH
sub-statements and the main query.
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) ;
当我尝试更新 first_insert_table
table 时,为什么此查询不更新 first_insert_table
的 column_of_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
只看到语句开始执行时存在的数据。
您的示例中也发生了同样的情况。 UPDATE
的 WHERE
子句只能找到整个语句开始时存在的行,因此它看不到 WITH
子句中插入的行。
此行为已记录 (7.8.2. Data-Modifying Statements in WITH
):
The sub-statements in
WITH
are executed concurrently with each other and with the main query. Therefore, when using data-modifying statements inWITH
, the order in which the specified updates actually happen is unpredictable. All the statements are executed with the same snapshot (see Chapter 13), so they cannot “see” one another's effects on the target tables. This alleviates the effects of the unpredictability of the actual order of row updates, and means thatRETURNING
data is the only way to communicate changes between differentWITH
sub-statements and the main query.