Felen:
-
RETURNING
sats saknas i den andraINSERT
uttalande. -
Ange en explicit lista med kolumner för din andra
INSERT
uttalande också. -
Ange inte
NULL
iINSERT
uttalanden om du vill att kolumnstandarden (seriekolumner?) ska slå in. Använd nyckelordetDEFAULT
eller bara inte nämna kolumnen alls.
Den bättre lösningen:
Använd datamodifierande CTE , tillgängligt sedan PostgreSQL 9.1 för att göra allt i ett uttalande och spara en overhead och rundresor till servern. (MySQL vet inget sådant, inte ens vanliga CTE).
Hoppa också över UPDATE
genom att ommodellera logiken. Hämta ett id med nextval()
, och nöj dig med bara två INSERT
uttalanden.
Om du antar denna datamodell (du borde ha angett det i din fråga):
CREATE TABLE institutions(i_id serial, name text, u_id int);
CREATE TABLE staff(user_id serial, username text, password text, i_id int);
Den här en query gör allt:
WITH x AS (
INSERT INTO staff(username, password, i_id) -- provide column list
VALUES ('$username', '$password', nextval('institutions_i_id_seq'))
RETURNING user_id, i_id
)
INSERT INTO institutions (i_id, u_id, name)
SELECT x.i_id, x.user_id, '$institution'
FROM x
RETURNING u_id, i_id; -- if you need the values back, else you are done
Datamodell
Du kanske funderar på att ändra din datamodell till en klassisk n:m-relation. Skulle inkludera dessa tabeller och primärnycklar:
staff (u_id serial PRIMARY KEY, ...)
institution (i_id serial PRIMARY KEY, ...)
institution_staff (i_id, u_id, ..., PRIMARY KEY(i_id, u_id)) -- implements n:m
Du kan alltid definiera institution_staff.i_id UNIQUE
, om en användare bara kan tillhöra en institution
.