PostgreSQL multi INSERT…RETURNING with multiple columns

Use data-modifying CTEs to chain your three INSERTs. Something like this:

WITH ins1 AS (
   INSERT INTO table1 (username, name,  surname)
   VALUES ('johnee','john','smith')
   RETURNING user_id
   )
, ins2 AS (
   INSERT INTO table2 (user_id, password)
   SELECT ins1.user_id, 'secret'
   FROM   ins1                            -- nothing to return here
   )
INSERT INTO table3 (user_id, adress, city, phone)
SELECT ins1.user_id, ...
FROM   ins1
RETURNING user_id;
  • It’s typically best to add a column definition list for INSERTs (except for special cases). Else, if the table structure changes, your code might break in surprising ways.

  • I omitted columns where you would just enter DEFAULT. Defaults are inserted automatically. Shorter, same result.

  • The final, optional RETURNING returns the resulting user_id – obviously from a sequence or some other default. It’s actually the user_id from table3, but that’s the same unless you have some triggers or other magic interfering.

More about data-modifying (a.k.a. “writable”) CTEs:

Leave a Comment