Thread: Re: [pgsql-ru-general] Возможно ли вставлять в несколько таблиц?

On Oct 31, 2011, at 10:12 AM, Dmitry E. Oboukhov wrote:

> Если пишем 
> 
> INSERT INTO table1 (a, b) VALUES (1, 2) RETURNING "id", '123' AS "name"
> 
> то возвращается результат вида
> 
> id | name
> 1  | 123
> 2  | 123
> 3  | 123
> 
> и так далее
> 
> Поскольку INSERT - SELECT работает то возникает соблазн написать
> 
> INSERT INTO table2 (table1_id, name)
> 
>  INSERT INTO table1 (a, b) VALUES (1, 2) RETURNING "id", '123' AS "name"
> 
> 
> Но такая запись не работает. Говорит что синтаксическая ошибка на
> втором INSERT. А в документации не вижу упоминания о том что в
> качестве query нельзя применять INSERT.
> 
> И вот поскольку здесь есть некая двоякость в том к чему относится
> RETURNING то я думаю, может я неправильно чет в синтаксисе делаю?

Даже если заключить второе выражение в скобки и поставить SELECT, работать
оно не будет.  RETURNING возвращает выражение, похожее на SELECT, но не 
создает промежуточный множество, которое можно использовать как вложенный
запрос. В 9.1 появилась поддержка writeable CTE, которые используют RETURNING
и позволяют реализовать INSERT сразу в 2 таблицы без процедур, например:

CREATE TABLE foo(a integer, b integer);
CREATE TABLE bar(a integer, b integer);

WITH insert_foo AS 
(INSERT INTO foo SELECT id, id * (-1) 
FROM generate_series(200,300) id RETURNING *) 
INSERT INTO bar SELECT * FROM insert_foo;

Отличие в том, что CTE как раз создает промежуточную таблицу результатов выражения
внтури WITH. К сожалению, это доступно только с 9.1

/A
> Даже если заключить второе выражение в скобки и поставить SELECT, работать
> оно не будет.  RETURNING возвращает выражение, похожее на SELECT, но не
> создает промежуточный множество, которое можно использовать как вложенный
> запрос. В 9.1 появилась поддержка writeable CTE, которые используют RETURNING
> и позволяют реализовать INSERT сразу в 2 таблицы без процедур, например:

> CREATE TABLE foo(a integer, b integer);
> CREATE TABLE bar(a integer, b integer);

> WITH insert_foo AS
> (INSERT INTO foo SELECT id, id * (-1)
> FROM generate_series(200,300) id RETURNING *)
> INSERT INTO bar SELECT * FROM insert_foo;

> Отличие в том, что CTE как раз создает промежуточную таблицу результатов выражения
> внтури WITH. К сожалению, это доступно только с 9.1

Спасибо!

Хороший повод съехать на 9.1

--

. ''`.                               Dmitry E. Oboukhov
: :’  :   email: unera@debian.org jabber://UNera@uvw.ru
`. `~’              GPGKey: 1024D / F8E26537 2006-11-21
  `- 1B23 D4F8 8EC0 D902 0555  E438 AB8C 00CF F8E2 6537

Attachment