2013-08-08 4 views
1

Возможно ли в PostgreSQL обновлять таблицу и вставлять данные в другую таблицу одновременно.SQL insert into AND update

Как

UPDATE table1 
SET column4=true 
AND INSERT into table2 
SELECT column1, column2, column3 
FROM table 1 
WHERE column1="peter" 
; 
+0

Ваши Postgres версии? –

ответ

2

На Postgres 9.1 или более поздней версии вы можете использовать что-то вроде:

WITH source AS (UPDATE table1 
       SET column4=true 
       WHERE column1='peter' 
       RETURNING column1, column2, column3) 
INSERT INTO table2 
SELECT column1, column2, column3 
FROM source; 
+1

Если вы пытаетесь узнать больше, найдите «записываемое общее табличное выражение». Это расширение PostgreSQL. –

+1

Хотя все это в одном утверждении, это не обязательно будет отображать одни и те же данные с того же момента в 'read commit'. Рассмотрим «повторяемость чтения» или большую изоляцию. –

0

Вы можете выполнить несколько операторов внутри транзакции, поэтому она все равно будет атомное изменение данных.

BEGIN; 

UPDATE table1 
SET column4=true; 

INSERT into table2 
SELECT column1, column2, column3 
FROM table 1 
WHERE column1="peter"; 

COMMIT; 

Если по какой-либо причине вставка терпит неудачу, вся транзакция не будет, а изменения будут попятился, включая обновление, который был выполнен перед оператором вставки.

+0

В Postgres 9.1+ вы можете делать любое количество DML в одном выражении с помощью CTE. –

+1

Это атомарно в смысле видимости при фиксации, но если вы находитесь в режиме чтения в режиме чтения, то два оператора все еще могут видеть разные данные, если кто-то другой заключает между ними. Я бы использовал, по крайней мере, изоляцию «повторяемого чтения», предпочтительно «сериализуемую». –

+0

Я имел в виду атомный, как внутри, либо все транзакции преуспевают или терпят неудачу. Я имею в виду, что это было бы целью попытаться написать два оператора DML в один, верно? – GolezTrol