Algo assim é possível?
INSERT INTO Table2 (val)
VALUES ((INSERT INTO Table1 (name) VALUES ('a_title') RETURNING id));
como usar o valor de retorno como valor para inserir uma linha em uma segunda tabela com uma referência à primeira tabela?
Algo assim é possível?
INSERT INTO Table2 (val)
VALUES ((INSERT INTO Table1 (name) VALUES ('a_title') RETURNING id));
como usar o valor de retorno como valor para inserir uma linha em uma segunda tabela com uma referência à primeira tabela?
Respostas:
Você pode fazer isso começando com Postgres 9.1:
with rows as (
INSERT INTO Table1 (name) VALUES ('a_title') RETURNING id
)
INSERT INTO Table2 (val)
SELECT id
FROM rows
Enquanto isso, se você estiver interessado apenas no id, poderá fazer isso com um gatilho:
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
por (some_query returning ...)
pode funcionar hoje em dia (não tentei).
A melhor prática para esta situação. Use RETURNING … INTO
.
INSERT INTO teams VALUES (...) RETURNING id INTO last_id;
Observe que isso é para PLPGSQL
RETURNING ... INTO
.
Em linha com a resposta dada por Denis de Bernardy ..
Se você deseja que o id seja retornado posteriormente também e deseja inserir mais coisas na Tabela 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
Você pode usar a lastval()
função:
Valor de retorno obtido mais recentemente com
nextval
para qualquer sequência
Então, algo assim:
INSERT INTO Table1 (name) VALUES ('a_title');
INSERT INTO Table2 (val) VALUES (lastval());
Isso funcionará bem, desde que ninguém chame nextval()
em qualquer outra sequência (na sessão atual) entre seus INSERTs.
Como Denis observou abaixo e eu avisei acima, usar lastval()
pode causar problemas se outra sequência for acessada usando nextval()
entre seus INSERTs. Isso poderia acontecer se houvesse um gatilho INSERT Table1
chamado manualmente nextval()
em uma sequência ou, mais provavelmente, se houvesse um INSERT em uma tabela com uma chave primária SERIAL
ouBIGSERIAL
. Se você quiser ser realmente paranóico (uma coisa boa, eles realmente são você para te pegar, afinal), você poderia usar, currval()
mas você precisa saber o nome da sequência relevante:
INSERT INTO Table1 (name) VALUES ('a_title');
INSERT INTO Table2 (val) VALUES (currval('Table1_id_seq'::regclass));
A sequência gerada automaticamente é geralmente nomeada t_c_seq
onde t
é o nome da tabela e c
é o nome da coluna, mas você sempre pode descobrir entrando psql
e dizendo:
=> \d table_name;
e, em seguida, olhar para o valor padrão da coluna em questão, por exemplo:
id | integer | not null default nextval('people_id_seq'::regclass)
FYI: lastval()
é, mais ou menos, a versão PostgreSQL do MySQL LAST_INSERT_ID
. Menciono isso apenas porque muitas pessoas estão mais familiarizadas com o MySQL do que com o PostgreSQL, portanto, vincular lastval()
a algo familiar pode esclarecer as coisas.
lastval
é que pode haver um INSERT baseado em sequência nas suas costas de um gatilho AFTER INSERT na Tabela1. Isso seria na sessão atual e, provavelmente, mudaria lastval()
quando você não estivesse esperando.