简体   繁体   English

更新无法使用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) ;

Why doesn't this query update column_of_first_insert_table column of first_insert_table , when I try to update first_insert_table table? 当我尝试更新first_insert_table表时,为什么此查询不更新first_insert_table column_of_first_insert_table列?

The reason why it doesn't perform the expected update is for the same reason why this simplified version of your example will not show the row being inserted in the WITH clause: 无法执行预期更新的原因与示例的简化版本不会显示在WITH子句中插入的行的原因相同:

with cte as (
  insert into first_insert_table (column_of_first_insert_table)
  values (10)
)
select * from first_insert_table

When executing the above statement, the INSERT does happen successfully, but the SELECT portion of the statement does not see it, because the SELECT only sees the data that existed at the moment the statement began executing. 执行上面的语句时, INSERT确实成功发生,但是该SELECT部分看不到它,因为SELECT仅看到该语句开始执行时存在的数据。

The same is happening in your example. 您的示例中也发生了同样的情况。 The WHERE clause of your UPDATE can only find rows that existed at the moment the whole statement began, so it doesn't see the row that was inserted in the WITH clause. UPDATEWHERE子句只能找到整个语句开始时存在的行,因此看不到在WITH子句中插入的行。

This behavior is documented ( 7.8.2. Data-Modifying Statements in WITH ): 这种行为被记录在案( 7.8.2在修改数据的语句。 WITH ):

The sub-statements in WITH are executed concurrently with each other and with the main query. WITH中的子语句彼此并与主查询并发执行。 Therefore, when using data-modifying statements in WITH , the order in which the specified updates actually happen is unpredictable. 因此,在WITH使用数据修改语句时,指定更新实际发生的顺序是不可预测的。 All the statements are executed with the same snapshot (see Chapter 13), so they cannot “see” one another's effects on the target tables. 所有语句都使用相同的快照执行(请参见第13章),因此它们无法“看到”彼此对目标表的影响。 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. 这减轻了行更新实际顺序的不可预测性的影响,并且意味着RETURNING数据是在不同的WITH子语句与主查询之间传递更改的唯一途径。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM