PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

डेटा-संशोधित CTE में INSERT कथनों को CASE व्यंजक के साथ संयोजित करना

आप नेस्ट नहीं कर सकते 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 . है तो कुछ भी प्रविष्ट नहीं करता है पंक्ति (पंक्तियों) को वापस नहीं करता है।

यदि आपको समवर्ती लेखन पहुंच से निपटना है जो इस ऑपरेशन के साथ संघर्ष कर सकता है तो त्वरित सुधार यह होगा कि आप इस कथन को उसी लेनदेन में चलाने से पहले शामिल तालिकाओं को लॉक कर दें।




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PostgreSQL शो टेबल समतुल्य (psql)

  2. django.db.utils.ProgrammingError:संबंध app_user manage.py परीक्षण के दौरान मौजूद नहीं है

  3. अद्यतन करने की आवश्यकता के बिना INSERT से ON CONFLICT के साथ पंक्तियाँ लौटाएँ

  4. PGConf India 2017 का बेसब्री से इंतजार है

  5. पोस्टग्रेस्क्ल में एक वर्चर कॉलम को एनम प्रकार में अपग्रेड करना