Lets say I have those tables:
CREATE TABLE buildings (
id_building serial4 NOT NULL,
street text NULL,
CONSTRAINT buildings_pkey PRIMARY KEY (id_building)
);
CREATE TABLE families (
id_family serial4 NOT NULL,
id_building int NOT NULL,
name text NULL,
CONSTRAINT families_pkey PRIMARY KEY (id_building),
CONSTRAINT families_id_building_fkey FOREIGN KEY (id_building) REFERENCES buildings (id_building)
);
CREATE TABLE people (
id_person serial4 NOT NULL,
id_family int NOT NULL,
name text NULL,
CONSTRAINT people_pkey PRIMARY KEY (id_person),
CONSTRAINT people_id_family_fkey FOREIGN KEY (id_family) REFERENCES buildings (id_family)
);
So that in a building you can have 0 or many families, and in every family you can have 1 or more people.
I need to make one query to insert in this connected tables without knowing the number of rows that are inserted. I know well this method https://stackoverflow.com/a/41595442 but I think the syntax would become quite complex rather fast.
So I'm exploring this system https://stackoverflow.com/a/41596194 that would be simpler to read and write. But is it robust and safe? My database is busy with many simultaneous inserts, even on those tables, from different sources and codes. I don't want to have inconsistencies in the reference keys.
The query would be something like this
BEGIN;
INSERT INTO buildings (street) VALUES ('St Michael''s Rd');
INSERT INTO families (id_building, name) VALUES (currval('buildings_id_seq'), 'White');
INSERT INTO people (id_family, name) VALUES (currval('families_id_seq'), 'John');
INSERT INTO people (id_family, name) VALUES (currval('families_id_seq'), 'Jenny');
INSERT INTO people (id_family, name) VALUES (currval('families_id_seq'), 'Pepy');
INSERT INTO families (id_building, name) VALUES (currval('buildings_id_seq'), 'Brown');
INSERT INTO people (id_family, name) VALUES (currval('families_id_seq'), 'Conny');
INSERT INTO buildings (street) VALUES ('Crossford St');
INSERT INTO buildings (street) VALUES ('Stockwell Park Cres');
INSERT INTO families (id_building, name) VALUES (currval('buildings_id_seq'), 'Smith');
INSERT INTO people (id_family, name) VALUES (currval('families_id_seq'), 'John');
END;
And I expect an output like this:
SELECT *
FROM buildings
-- 1, St Michael''s Rd
-- 2, Crossford St
-- 3, Stockwell Park Cres
SELECT *
FROM families
-- 1, 1, White
-- 2, 1, Brown
-- 3, 3, Smith
SELECT *
FROM people
-- 1, 1, John
-- 2, 1, Jenny
-- 3, 1, Pepy
-- 4, 2, Conny
-- 5, 3, John
BEGIN
-END
block should assure that, right?END;
would then generate a warning).currval('families_id_seq')
statement into a separate statement, then pass that value to each of theINSERT INTO people
statements? It would make the intent of your code clearer.