Vous ne pouvez pas imbriquer INSERT instructions dans un CASE expression. D'après ce que je vois, cette approche complètement différente devrait le faire :
Hypothèses
-
Vous n'avez pas réellement besoin du
SELECTexterne . -
dm_name/rm_namesont définis uniques dansdm/rmet non vide (<> ''). Vous devriez avoir unCHECKcontrainte pour s'en assurer. -
Colonne par défaut pour les deux
d_idetr_idenzsont NULL (par défaut).
dm_name et rm_name mutuellement exclusif
Si les deux ne sont jamais présents en même temps.
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;
Le FULL JOIN .. ON FALSE produit une table dérivée avec toutes les lignes de d1 et r1 ajouté avec NULL pour l'autre colonne respective (pas de chevauchement entre les deux). Nous avons donc juste besoin d'un INSERT au lieu de deux. Optimisation mineure.
dm_name et rm_name peuvent coexister
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;
Remarques
Les deux versions fonctionnent également si aucune n'existe.
INSERT n'insère rien si le SELECT ne renvoie pas de ligne(s).
Si vous devez gérer un accès en écriture concurrent qui pourrait entrer en conflit avec cette opération, la solution rapide consisterait à verrouiller les tables impliquées avant d'exécuter cette instruction dans la même transaction.