В PostgreSQL 8.2 было добавлено выражение RETURNING для INSERT/UPDATE/DELETE запросов. К сожалению, оно не могло быть использовано как источник строк для всего в SQL.
insert into table_backup delete from table where ... returning *;В прочем, это и сейчас не возможно, но был сделан один шаг в правильном направлении, благодаря патчу от Tom Lane 31го Октября:
Позволяет SQL-функциям возвращать вывод INSERT/UPDATE/DELETE RETURNING выражений, а не только SELECT как прежде.Как это работает? Всё просто. Начнём с тестовой таблицы:
Дополнительный эффект этого патча таков, что когда возвращающая множество SQL функция используется в FROM, производительность увеличивается за счёт того, что вывод накапливается в tuplestore внутри функции, в отличие от менее эффективного значение-за-вызов механизма.
# create table test (i int4);С тестовым контентом:
CREATE TABLE
# insert into test select generate_series(1, 10);Теперь создадим свою SQL функцию удаляющую строки:
INSERT 0 10
CREATE function delete_from_test_returning(INT4) RETURNS setof test as $$Как видно, функция очень проста.
DELETE FROM test WHERE i <= $1 returning *
$$ language sql;
Теперь используем её для бэкапа удаленных строк:
# create table delete_backup as select * from delete_from_test_returning(3);И проверим содержание обеих таблиц:
SELECT
# select * from test;Конечно, я мог бы сделать это раньше в pl/pgsql функции, которая бы пробегалась по всем возвращаемым строкам, но в данном случае это определённо будет быстрее.
i
----
4
5
6
7
8
9
10
(7 rows)
# select * from delete_backup;
i
---
1
2
3
(3 rows)
No comments:
Post a Comment