आप नेस्ट नहीं कर सकते INSERT
CASE
. में कथन अभिव्यक्ति। मैं जो देख रहा हूं उससे व्युत्पन्न, यह पूरी तरह से अलग दृष्टिकोण यह करना चाहिए:
मान्यताएं
-
आपको वास्तव में बाहरी
SELECT
. की आवश्यकता नहीं है । -
dm_name
/rm_name
dm
. में अद्वितीय परिभाषित हैं /rm
और खाली नहीं (<> ''
) आपके पास एकCHECK
होना चाहिए सुनिश्चित करने के लिए बाधा। -
d_id
both दोनों के लिए कॉलम डिफ़ॉल्ट औरr_id
z
. में NULL (डिफ़ॉल्ट) हैं।
dm_name
और rm_name
परस्पर अनन्य
यदि दोनों एक ही समय पर कभी उपस्थित नहीं होते हैं।
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
d1
. से सभी पंक्तियों के साथ एक व्युत्पन्न तालिका तैयार करता है और r1
संबंधित अन्य कॉलम के लिए NULL के साथ जोड़ा गया (दोनों के बीच कोई ओवरलैप नहीं)। तो हमें बस एक INSERT
की आवश्यकता है दो के बजाय। मामूली अनुकूलन।
dm_name
और rm_name
एक साथ रह सकते हैं
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;
नोट
दोनों संस्करण भी काम करते हैं यदि कोई मौजूद नहीं है।
INSERT
अगर SELECT
. है तो कुछ भी प्रविष्ट नहीं करता है पंक्ति (पंक्तियों) को वापस नहीं करता है।
यदि आपको समवर्ती लेखन पहुंच से निपटना है जो इस ऑपरेशन के साथ संघर्ष कर सकता है तो त्वरित सुधार यह होगा कि आप इस कथन को उसी लेनदेन में चलाने से पहले शामिल तालिकाओं को लॉक कर दें।