Могу ли я использовать возвращаемое значение INSERT... RETURNING в другом INSERT? - программирование
Подтвердить что ты не робот

Могу ли я использовать возвращаемое значение INSERT... RETURNING в другом INSERT?

Возможно ли подобное?

INSERT INTO Table2 (val)
VALUES ((INSERT INTO Table1 (name) VALUES ('a_title') RETURNING id));

как использовать возвращаемое значение как значение для вставки строки во вторую таблицу со ссылкой на первую таблицу?

4b9b3361

Ответ 1

Вы можете сделать это, начиная с Postgres 9.1:

with rows as (
INSERT INTO Table1 (name) VALUES ('a_title') RETURNING id
)
INSERT INTO Table2 (val)
SELECT id
FROM rows

Между тем, если вас интересует только идентификатор, вы можете сделать это с помощью триггера:

create function t1_ins_into_t2()
  returns trigger
as $$
begin
  insert into table2 (val) values (new.id);
  return new;
end;
$$ language plpgsql;

create trigger t1_ins_into_t2
  after insert on table1
for each row
execute procedure t1_ins_into_t2();

Ответ 2

Лучшая практика для этой ситуации. Используйте RETURNING … INTO.

INSERT INTO teams VALUES (...) RETURNING id INTO last_id;

Ответ 3

Вы можете использовать функцию lastval():

Возвращаемое значение, полученное последним с помощью nextval для любой последовательности

Так что-то вроде этого:

INSERT INTO Table1 (name) VALUES ('a_title');
INSERT INTO Table2 (val)  VALUES (lastval());

Это будет работать нормально, пока никто не называет nextval() в любой другой последовательности (в текущем сеансе) между вашими INSERT.

Как Denis, как указано ниже, и я предупреждал об этом выше, использование lastval() может вызвать у вас проблемы при доступе к другой последовательности с помощью nextval() между вашими INSERT, Это может произойти, если на этапе Table1 был запущен триггер INSERT, который вручную вызвал nextval() в последовательности или, более вероятно, сделал INSERT в таблице с SERIAL или BIGSERIAL первичный ключ. Если вы хотите быть на самом деле параноиком (хорошо, вам действительно нужно, чтобы вы все получили), тогда вы можете использовать currval() но вам нужно знать название соответствующей последовательности:

INSERT INTO Table1 (name) VALUES ('a_title');
INSERT INTO Table2 (val)  VALUES (currval('Table1_id_seq'::regclass));

Автоматически сгенерированная последовательность обычно называется t_c_seq, где t - это имя таблицы, а c - это имя столбца, но вы всегда можете узнать, перейдя в psql и говоря:

=> \d table_name;

а затем посмотрев значение по умолчанию для рассматриваемого столбца, например:

id | integer | not null default nextval('people_id_seq'::regclass)

FYI: lastval() является, более или менее, версией MySQL PostgreSQL LAST_INSERT_ID. Я только упоминаю об этом, потому что многие люди больше знакомы с MySQL, чем PostgreSQL, поэтому привязка lastval() к чему-то знакомому может прояснить ситуацию.

Ответ 4

В соответствии с ответом Дениса де Бернарди.

Если вы хотите, чтобы и потом возвращался идентификатор, и хотите вставить больше вещей в таблицу2:

with rows as (
INSERT INTO Table1 (name) VALUES ('a_title') RETURNING id
)
INSERT INTO Table2 (val, val2, val3)
SELECT id, 'val2value', 'val3value'
FROM rows
RETURNING val

Ответ 5

table_ex

id default nextval ('table_id_seq':: regclass),

camp1 varchar

camp2 varchar

INSERT INTO table_ex(camp1,camp2) VALUES ('xxx','123') RETURNING id