Sie können INSERT
nicht verschachteln Anweisungen in einem CASE
Ausdruck. Abgeleitet von dem, was ich sehe, sollte dieser völlig andere Ansatz es tun:
Annahmen
-
Das äußere
SELECT
brauchen Sie eigentlich nicht . -
dm_name
/rm_name
sind eindeutig indm
definiert /rm
und nicht leer (<> ''
). Sie sollten einenCHECK
haben Einschränkung, um sicherzustellen. -
Spaltenvorgabe für beide
d_id
undr_id
inz
sind NULL (Standard).
dm_name
und rm_name
sich gegenseitig ausschließen
Wenn beide nie gleichzeitig vorhanden sind.
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;
Der FULL JOIN .. ON FALSE
erzeugt eine abgeleitete Tabelle mit allen Zeilen aus d1
und r1
angehängt mit NULL für die jeweils andere Spalte (keine Überschneidung zwischen beiden). Wir brauchen also nur ein INSERT
statt zwei. Kleinere Optimierung.
dm_name
und rm_name
koexistieren
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;
Notizen
Beide Versionen funktionieren auch, wenn keine vorhanden ist.
INSERT
fügt nichts ein, wenn SELECT
gibt keine Zeile(n) zurück.
Wenn Sie mit gleichzeitigem Schreibzugriff umgehen müssen, der mit dieser Operation in Konflikt geraten könnte, besteht die schnelle Lösung darin, die betroffenen Tabellen zu sperren, bevor Sie diese Anweisung in derselben Transaktion ausführen.