Question

I`m building a database with Postgres 9.3 as a backend, having 3 tables:

table1 (user_id, username, name, surname, emp_date)
table2 (pass_id, user_id, password)
table3 (user_dt_id, user_id, adress, city, phone)

As can be seen table2 and table3 are child tables of table1.
I can extract the user_id of a newly inserted row in table1 (parent):

INSERT INTO "table1" (default,'johnee','john','smith',default) RETURNING userid;

I need to insert the newly extracted id (from table1) into user_id columns of table2 and table3 along with other data unique for those tables. Basically 3 X INSERT ...
How do I do that?

Était-ce utile?

La solution

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:

Autres conseils

Insert master-detail using function

CREATE OR REPLACE FUNCTION apps.usp_bazar_list_insert_1(
    ip_userid character varying,
    ip_mobileno character varying,
    ip_bazarlisttext text,
    data_details text)
    RETURNS TABLE(id integer) 
    LANGUAGE 'plpgsql'

    COST 100
    VOLATILE 
    ROWS 1000
    
AS $BODY$
DECLARE master_id integer;
BEGIN
insert into apps.bazar_list(action_by,mobile_no,bazarlisttext,action_date) 
select ip_userId,ip_mobileNo,ip_bazarListText,now() returning list_id into master_id;

insert into apps.bazar_list_images(list_id,action_date,image_name) 
select master_id,now(),image_name from json_populate_recordset(NULL::apps.bazar_list_images, 
                                   data_details::json);
RETURN QUERY
        select 1;
    
END;
$BODY$;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top