postgresql sql-returning

postgresql - ¿Puedo usar el valor de retorno de INSERTAR... VOLVER en otro INSERTAR?



sql-returning (6)

Es algo como esto posible?

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?


table_ex

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

camp1 varchar

camp2 varchar

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


De acuerdo con la respuesta de Denis de Bernardy.

Si también desea que se devuelva el id posteriormente y desea insertar más elementos 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


La mejor práctica para esta situación. Use RETURNING … INTO

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


Puede usar la función lastval() :

Valor de retorno obtenido más recientemente con nextval para cualquier secuencia

Entonces algo como esto:

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

Esto funcionará bien siempre que nadie llame a nextval() en cualquier otra secuencia (en la sesión actual) entre sus INSERT.

Como Denis señaló a continuación y advertí sobre lo anterior, usar lastval() puede lastval() problemas si se accede a otra secuencia usando nextval() entre sus INSERT. Esto podría suceder si hubiera un disparador INSERT en la Table1 que llamara manualmente a nextval() en una secuencia o, más probablemente, hiciera un INSERTAR en una tabla con una clave primaria SERIAL o BIGSERIAL . Si quieres ser realmente paranoico (algo bueno, ellos realmente son tú para lastval() después de todo), entonces podrías usar lastval() pero necesitarías 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 suele llamarse t_c_seq donde t es el nombre de la tabla c es el nombre de la columna, pero siempre puede averiguar yendo a psql y diciendo:

=> /d table_name;

y luego mirando el valor predeterminado para la columna en cuestión, por ejemplo:

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

FYI: lastval() es, más o menos, la versión de PostgreSQL de LAST_INSERT_ID de MySQL. Solo menciono esto porque mucha gente está más familiarizada con MySQL que con PostgreSQL, por lo que vincular a lastval() con algo familiar podría aclarar las cosas.


Puedes hacerlo comenzando con Postgres 9.1:

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

Mientras tanto, si solo estás interesado en la identificación, puedes hacerlo con un desencadenador:

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();


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)