Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Store and reuse value returned by INSERT ... RETURNING

In PostgreSQL, it is possible to put RETURNING at the end of an INSERT statement to return, say, the row's primary key value when that value is automatically set by a SERIAL type.

Question:

How do I store this value in a variable that can be used to insert values into other tables? Note that I want to insert the generated id into multiple tables. A WITH clause is, as far as I understand, only useful for a single insert. I take it that this will probably have to be done in PHP.

This is really the result of bad design; without a natural key, it is difficult to grab a unique row unless you have a handle on the primary key;

like image 931
Adam Avatar asked Mar 26 '13 01:03

Adam


People also ask

What does insert query return?

An SQL INSERT statement writes new rows of data into a table. If the INSERT activity is successful, it returns the number of rows inserted into the table.

What does Postgres return on insert?

In an INSERT , the data available to RETURNING is the row as it was inserted. This is not so useful in trivial inserts, since it would just repeat the data provided by the client. But it can be very handy when relying on computed default values.

What is Upsert in PostgreSQL?

The UPSERT statement is a DBMS feature that allows a DML statement's author to either insert a row or if the row already exists, UPDATE that existing row instead. That is why the action is known as UPSERT (simply a mix of Update and Insert).


1 Answers

... that can be used to insert values into other tables?

You can even do that in a single SQL statement using a data-modifying CTE:

WITH ins1 AS (
   INSERT INTO tbl1(txt)
   VALUES ('foo')
   RETURNING tbl1_id
   )
INSERT INTO tbl2(tbl1_id)
SELECT * FROM ins1

Requires PostgreSQL 9.1 or later.

db<>fiddle here (Postgres 13)
Old sqlfiddle (Postgres 9.6)

Reply to question update

You can also insert into multiple tables in a single query:

WITH ins1 AS (
   INSERT INTO tbl1(txt)
   VALUES ('bar')
   RETURNING tbl1_id
   )
 , ins2 AS (
   INSERT INTO tbl2(tbl1_id)
   SELECT tbl1_id FROM ins1
   )
INSERT INTO tbl3(tbl1_id)
SELECT tbl1_id FROM ins1;
like image 151
Erwin Brandstetter Avatar answered Oct 19 '22 17:10

Erwin Brandstetter