sql >> Database teknologi >  >> RDS >> PostgreSQL

Kombination af INSERT-sætninger i en datamodificerende CTE med et CASE-udtryk

Du kan ikke indlejre INSERT udsagn i en CASE udtryk. Ud fra hvad jeg ser, burde denne helt anderledes tilgang gøre det:

Forudsætninger

  • Du behøver faktisk ikke den ydre SELECT .

  • dm_name / rm_name er defineret unikke i dm / rm og ikke tom (<> '' ). Du skal have en CHECK begrænsning for at sikre.

  • Kolonnestandard for både d_id og r_id i z er NULL (standard).

dm_name og rm_name gensidigt udelukker

Hvis begge aldrig er til stede på samme tid.

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 producerer en afledt tabel med alle rækker fra d1 og r1 tilføjet NULL for den respektive anden kolonne (ingen overlap mellem de to). Så vi mangler bare én INSERT i stedet for to. Mindre optimering.

dm_name og rm_name kan sameksistere

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;

Bemærkninger

Begge versioner fungerer også, hvis ingen af ​​dem findes.

INSERT indsætter intet, hvis SELECT returnerer ikke række(r).

Hvis du skal håndtere samtidig skriveadgang, der kan være i konflikt med denne handling, ville den hurtige løsning være at låse involverede tabeller, før du kører denne sætning i samme transaktion.




  1. Syntaksfejl på grund af brug af et reserveret ord som et tabel- eller kolonnenavn i MySQL

  2. .patch_storage

  3. Hvad er standardbegrænsning i SQL Server - SQL Server / TSQL vejledning del 90

  4. Trin for trin opgraderingsproces til R12.2 Upgrade part -2 (Main Upgrade Driver for R12.2.0)