Błędy:
-
RETURNING
brak klauzuli w drugimINSERT
oświadczenie. -
Podaj wyraźną listę kolumn dla drugiego
INSERT
również oświadczenie. -
Nie podawaj
NULL
wINSERT
oświadczenia jeśli chcesz, aby uruchamiana była domyślna kolumna (kolumny szeregowe?). Użyj słowa kluczowegoDEFAULT
lub po prostu w ogóle nie wspominaj o kolumnie.
Lepsze rozwiązanie:
Użyj CTE modyfikacji danych , dostępny od wersji PostgreSQL 9.1, aby zrobić to wszystko w jednym oświadczeniu i zaoszczędzić na kosztach i podróży w obie strony do serwera. (MySQL nic takiego nie zna, nawet zwykłe CTE).
Pomiń także UPDATE
poprzez przemodelowanie logiki. Pobierz jeden identyfikator za pomocą nextval()
i wystarczy dwa INSERT
oświadczenia.
Zakładając ten model danych (powinieneś był podać go w swoim pytaniu):
CREATE TABLE institutions(i_id serial, name text, u_id int);
CREATE TABLE staff(user_id serial, username text, password text, i_id int);
Ten jeden zapytanie to wszystko:
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
Model danych
Możesz pomyśleć o zmianie modelu danych na klasyczną relację n:m. Dołączyłoby to następujące tabele i klucze podstawowe:
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
Zawsze możesz zdefiniować institution_staff.i_id UNIQUE
, jeśli użytkownik może należeć tylko do jednej institution
.