Bạn không thể lồng INSERT câu lệnh trong CASE biểu hiện. Xuất phát từ những gì tôi thấy, cách tiếp cận hoàn toàn khác này sẽ làm được điều đó:
Giả định
-
Bạn không thực sự cần
SELECTbên ngoài . -
dm_name/rm_nameđược định nghĩa duy nhất trongdm/rmvà không trống (<> ''). Bạn phải cóCHECKràng buộc để đảm bảo. -
Cột mặc định cho cả
d_idvàr_idtrongzlà NULL (mặc định).
dm_name và rm_name loại trừ lẫn nhau
Nếu cả hai không bao giờ xuất hiện cùng một lúc.
WITH d1 AS (
INSERT INTO d (dm_id)
SELECT dm.dm_id
FROM import
JOIN dm USING (dm_name)
RETURNING d_id
)
, r1 AS (
INSERT INTO r (rm_id)
SELECT rm.rm_id
FROM import
JOIN rm USING (rm_name)
RETURNING r_id
)
, z1 AS (
INSERT INTO z (d_id, r_id)
SELECT d_id, r_id
FROM d1 FULL JOIN r1 ON FALSE
RETURNING z_id
)
INSERT INTO port (z_id)
SELECT z_id
FROM z1;
FULL JOIN .. ON FALSE tạo một bảng dẫn xuất với tất cả các hàng từ d1 và r1 được nối với NULL cho cột khác tương ứng (không có chồng chéo giữa hai cột). Vì vậy, chúng tôi chỉ cần một INSERT thay vì hai. Tối ưu hóa nhỏ.
dm_name và rm_name có thể cùng tồn tại
WITH i AS (
SELECT dm.dm_id, rm.rm_id
FROM import
LEFT JOIN dm USING (dm_name)
LEFT JOIN rm USING (rm_name)
)
, d1 AS (
INSERT INTO d (dm_id)
SELECT dm_id FROM i WHERE dm_id IS NOT NULL
RETURNING dm_id, d_id
)
, r1 AS (
INSERT INTO r (rm_id)
SELECT rm_id FROM i WHERE rm_id IS NOT NULL
RETURNING rm_id, r_id
)
, z1 AS (
INSERT INTO z (d_id, r_id)
SELECT d1.d_id, r1.r_id
FROM i
LEFT JOIN d1 USING (dm_id)
LEFT JOIN r1 USING (rm_id)
WHERE d1.dm_id IS NOT NULL OR
r1.rm_id IS NOT NULL
RETURNING z_id
)
INSERT INTO port (z_id)
SELECT z_id FROM z1;
Ghi chú
Cả hai phiên bản đều hoạt động nếu cả hai phiên bản đều không tồn tại.
INSERT không chèn gì nếu SELECT không trả về (các) hàng.
Nếu bạn phải đối phó với quyền truy cập ghi đồng thời có thể xung đột với thao tác này, cách khắc phục nhanh sẽ là khóa các bảng có liên quan trước khi bạn chạy câu lệnh này trong cùng một giao dịch.