CTE и обновление данных

Рейтинг: 0Ответов: 1Опубликовано: 14.04.2023

Почему при выполнении данного запроса в таблицу table2 вставляется запись с table1 со значение до обновления в CTE? Ведь транзакция одна и планировщик показывает что сначала выполняется обновление данных.

до: table1(id=1, name='Bob')

with cte as (update table1 set name = 'John' where id = 1) insert into table2 select * from table1 where id = 1;

после: table1(id=1, name='John'), table2(id=1, name='Bob')

Ответы

▲ 2Принят

Это задокументировано

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.

Все меняющие данные части CTE оперируют одним и тем же снимком видимости.

Чтобы оперировать результатом запроса, используйте RETURNING и обращайтесь к данным этого запроса

with cte as (
  update table1 set name = 'John' where id = 1
  returning *
) 
insert into table2 select * from cte;