Чи можливо щось подібне?
INSERT INTO Table2 (val)
VALUES ((INSERT INTO Table1 (name) VALUES ('a_title') RETURNING id));
як використання поверненого значення як значення для вставки рядка у другу таблицю з посиланням на першу таблицю?
Відповіді:
Ви можете зробити це, починаючи з 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();
rows
на (some_query returning ...)
може працювати сьогодні (не пробував).
Найкраща практика для цієї ситуації. Використовуйте RETURNING … INTO
.
INSERT INTO teams VALUES (...) RETURNING id INTO last_id;
Зверніть увагу, це для PLPGSQL
RETURNING ... INTO
.
Відповідно до відповіді Дениса де Бернарді ..
Якщо ви хочете, щоб ідентифікатор повертався згодом, і ви хочете вставити більше речей у Таблицю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
Ви можете використовувати lastval()
функцію:
Повернене значення, отримане за останнім часом
nextval
для будь-якої послідовності
Отож приблизно так:
INSERT INTO Table1 (name) VALUES ('a_title');
INSERT INTO Table2 (val) VALUES (lastval());
Це буде працювати нормально, доки ніхто не звернеться nextval()
до будь-якої іншої послідовності (у поточному сеансі) між вашими INSERT.
Як зазначив Денис нижче, і я попереджав про це вище, використання lastval()
може призвести до проблем, якщо доступ до іншої послідовності відбувається nextval()
між вашими INSERT. Це може статися , якщо був вставити тригер , Table1
який вручну називається 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()
на щось знайоме може пояснити речі.
lastval
полягає в тому, що за вашою спиною може бути INSERT на основі послідовності від тригера AFTER INSERT на Таблиці1. Це буде в поточній сесії і, мабуть, зміниться, lastval()
коли ви цього не очікуєте.