Các lỗi:
-
RETURNING
thiếu mệnh đề trongINSERT
thứ hai tuyên bố. -
Cung cấp danh sách cột rõ ràng cho
INSERT
thứ hai của bạn câu lệnh cũng vậy. -
Không cung cấp
NULL
trongINSERT
tuyên bố nếu bạn muốn mặc định cột (các cột nối tiếp?) bắt đầu. Hãy sử dụng từ khóaDEFAULT
hoặc hoàn toàn không đề cập đến cột.
Giải pháp tốt hơn:
Sử dụng CTE chuyển đổi dữ liệu , có sẵn kể từ PostgreSQL 9.1 để thực hiện tất cả trong một câu lệnh và tiết kiệm chi phí và các chuyến đi vòng quanh máy chủ. (MySQL không biết gì về loại này, thậm chí không phải là CTE đơn giản).
Ngoài ra, bỏ qua UPDATE
bằng cách mô hình lại logic. Truy xuất một id bằng nextval()
và thực hiện chỉ với hai INSERT
tuyên bố.
Giả sử mô hình dữ liệu này (bạn nên cung cấp mô hình đó trong câu hỏi của mình):
CREATE TABLE institutions(i_id serial, name text, u_id int);
CREATE TABLE staff(user_id serial, username text, password text, i_id int);
Cái này một truy vấn hiện tất cả:
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
Mô hình dữ liệu
Bạn có thể nghĩ đến việc thay đổi mô hình dữ liệu của mình thành mối quan hệ n:m cổ điển. Có thể bao gồm các bảng và khóa chính sau:
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
Bạn luôn có thể xác định institution_staff.i_id UNIQUE
, nếu người dùng chỉ có thể thuộc về một institution
.