¿Es posible algo como esto?
INSERT INTO Table2 (val)
VALUES ((INSERT INTO Table1 (name) VALUES ('a_title') RETURNING id));
como usar el valor de retorno como valor para insertar una fila en una segunda tabla con una referencia a la primera tabla?
postgresql
sql-returning
Eike Cochu
fuente
fuente
rows
con(some_query returning ...)
podría funcionar hoy en día (no lo he probado).La mejor práctica para esta situación. Utilice
RETURNING … INTO
.INSERT INTO teams VALUES (...) RETURNING id INTO last_id;
Tenga en cuenta que esto es para PLPGSQL
fuente
RETURNING ... INTO
.En consonancia con la respuesta de Denis de Bernardy ..
Si desea que la identificación también se devuelva después y desea insertar más cosas en Table2:
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
fuente
DO $$ DECLARE tableId integer; BEGIN INSERT INTO Table1 (name) VALUES ('a_title') RETURNING id INTO tableId; INSERT INTO Table2 (val) VALUES (tableId); END $$;
Probado con psql (10.3, servidor 9.6.8)
fuente
Puede utilizar la
lastval()
función:Entonces algo como esto:
INSERT INTO Table1 (name) VALUES ('a_title'); INSERT INTO Table2 (val) VALUES (lastval());
Esto funcionará bien siempre que nadie llame
nextval()
a ninguna otra secuencia (en la sesión actual) entre sus INSERT.Como Denis señaló a continuación y sobre lo que advertí anteriormente, el uso
lastval()
puedenextval()
causarle problemas si accede a otra secuencia entre sus INSERT. Esto podría suceder si hubiera un desencadenador INSERT enTable1
ese llamado manualmentenextval()
en una secuencia o, más probablemente, hizo un INSERT en una tabla con una clave primariaSERIAL
oBIGSERIAL
. Si quieres ser realmente paranoico (una cosa buena, que son en realidad a conseguir que después de todo), entonces se podría usarcurrval()
, pero que había necesidad de saber el nombre de la secuencia relevante:INSERT INTO Table1 (name) VALUES ('a_title'); INSERT INTO Table2 (val) VALUES (currval('Table1_id_seq'::regclass));
La secuencia generada automáticamente generalmente se nombra
t_c_seq
dondet
está el nombre de la tabla yc
el nombre de la columna, pero siempre puede averiguarlo ingresandopsql
y diciendo:y luego mirando el valor predeterminado para la columna en cuestión, por ejemplo:
FYI:
lastval()
es, más o menos, la versión PostgreSQL de MySQLLAST_INSERT_ID
. Solo menciono esto porque mucha gente está más familiarizada con MySQL que con PostgreSQL, por lo que vincularlastval()
a algo familiar podría aclarar las cosas.fuente
lastval
es que podría haber un INSERT basado en una secuencia a sus espaldas desde un disparador AFTER INSERT en Table1. Eso sería en la sesión actual y, presumiblemente, cambiaríalastval()
cuando no lo esperas.INSERT INTO table_ex(camp1,camp2) VALUES ('xxx','123') RETURNING id
fuente