Anda tidak dapat membuat sarang INSERT
pernyataan dalam CASE
ekspresi. Berasal dari apa yang saya lihat, pendekatan yang sama sekali berbeda ini seharusnya berhasil:
Asumsi
-
Anda sebenarnya tidak memerlukan
SELECT
outer bagian luar . -
dm_name
/rm_name
didefinisikan unik didm
/rm
dan tidak kosong (<> ''
). Anda harus memilikiCHECK
kendala untuk memastikan. -
Kolom default untuk keduanya
d_id
danr_id
diz
adalah NULL (default).
dm_name
dan rm_name
saling eksklusif
Jika keduanya tidak pernah hadir secara bersamaan.
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
menghasilkan tabel turunan dengan semua baris dari d1
dan r1
ditambahkan dengan NULL untuk masing-masing kolom lainnya (tidak ada tumpang tindih di antara keduanya). Jadi kita hanya perlu satu INSERT
bukannya dua. Pengoptimalan kecil.
dm_name
dan rm_name
dapat hidup berdampingan
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;
Catatan
Kedua versi juga berfungsi jika tidak ada.
INSERT
tidak menyisipkan apa pun jika SELECT
tidak mengembalikan baris.
Jika Anda harus berurusan dengan akses tulis bersamaan yang dapat bertentangan dengan operasi ini, perbaikan cepatnya adalah dengan mengunci tabel yang terlibat sebelum Anda menjalankan pernyataan ini dalam transaksi yang sama.