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

PostgreSQL:बहुमुखी INSERT

जब आप PostgreSQL में INSERT कथन के बारे में सोचते हैं तो एक तालिका में एक पंक्ति सम्मिलित करना आपके दिमाग में आता है। हालाँकि, इसमें कुछ और तरकीबें हैं जो ऊपर की आस्तीन हैं! INSERT के साथ कुछ और दिलचस्प चीज़ें खोजने के लिए पढ़ें जो आप कर सकते हैं।

बल्क में कॉपी करना

मान लें कि आप समय-समय पर किसी तालिका के स्नैपशॉट कैप्चर करना चाहते हैं - तालिका की सभी पंक्तियों को किसी अन्य तालिका में कॉपी किया जाना चाहिए, एक अतिरिक्त टाइमस्टैम्प कॉलम के साथ जो स्नैपशॉट लिया गया था। यहां बताया गया है कि आप पहली बार तालिका कैसे बना और भर सकते हैं:

demo=# SELECT * FROM mytable;
 ticker | quote
--------+-------
 FOO    | $4.01
 BAR    | $1.42
(2 rows)

demo=# CREATE TABLE snaps_of_mytable AS
demo-#   SELECT current_timestamp AS snapped_at, *
demo-#     FROM mytable;
SELECT 2
demo=#
demo=# SELECT * FROM snaps_of_mytable ;
         snapped_at          | ticker | quote
-----------------------------+--------+-------
 2018-10-09 04:16:22.3613+00 | FOO    | $4.01
 2018-10-09 04:16:22.3613+00 | BAR    | $1.42
(2 rows)

और तब से, आप INSERT..SELECT . का उपयोग कर सकते हैं एक टेबल से पंक्तियों को कॉपी करने और दूसरे में डालने के लिए INSERT स्टेटमेंट का रूप। आप गंतव्य तालिका पंक्ति में भी अतिरिक्त मान भर सकते हैं।

demo=# INSERT INTO snaps_of_mytable
demo-#   SELECT current_timestamp AS snapped_at, *
demo-#     FROM mytable;
INSERT 0 2
demo=#
demo=# SELECT * FROM snaps_of_mytable ;
          snapped_at           | ticker | quote
-------------------------------+--------+-------
 2018-10-09 04:16:22.3613+00   | FOO    | $4.01
 2018-10-09 04:16:22.3613+00   | BAR    | $1.42
 2018-10-09 04:18:53.432224+00 | BAR    | $1.42
 2018-10-09 04:18:53.432224+00 | FOO    | $4.10
(4 rows)

अप्सर्ट्स

PostgreSQL 9.5 में, ON CONFLICT INSERT में क्लॉज जोड़ा गया। यह एप्लिकेशन डेवलपर्स को कम कोड लिखने और SQL में अधिक काम करने देता है।

यहाँ कुंजी, मान युग्मों की एक तालिका है:

demo=# SELECT * FROM kv;
 key  |   value
------+-----------
 host | 127.0.0.1
 port | 5432
(2 rows)

एक सामान्य उपयोग का मामला केवल एक पंक्ति सम्मिलित करना है यदि वह मौजूद नहीं है - और यदि यह होता है, तो अधिलेखित न करें। यह ON CONFLICT..DO NOTHING . के साथ किया जाता है INSERT कथन का खंड:

demo=# INSERT INTO kv (key, value) VALUES ('port', '3306')
demo-# ON CONFLICT (key) DO NOTHING;
INSERT 0 0
demo=# SELECT * FROM kv;
 key  |   value
------+-----------
 host | 127.0.0.1
 port | 5432
(2 rows)

एक अन्य सामान्य उपयोग एक पंक्ति सम्मिलित करना है यदि यह मौजूद नहीं है, और यदि ऐसा है, तो मूल्य को अपडेट करें। यह ON CONFLICT..DO UPDATE . के साथ किया जा सकता है खंड।

demo=# INSERT INTO kv (key, value) VALUES ('host', '10.0.10.1')
demo-# ON CONFLICT (key) DO UPDATE SET value=EXCLUDED.value;
INSERT 0 1
demo=# INSERT INTO kv (key, value) VALUES ('ssl', 'off')
demo-# ON CONFLICT (key) DO UPDATE SET value=EXCLUDED.value;
INSERT 0 1
demo=# SELECT * FROM kv;
 key  |   value
------+-----------
 host | 10.0.10.1
 port | 5432
 ssl  | off
(3 rows)

पहले मामले में 'होस्ट' के मूल्य को नए मान के साथ अधिलेखित कर दिया गया था, और दूसरे मामले में 'एसएसएल' का मान तीसरी पंक्ति के रूप में डाला गया था।

DO UPDATE . के साथ और भी अधिक परिष्कृत उपयोग के मामलों को महसूस किया जा सकता है . नीचे दी गई तालिका पर विचार करें, जहां कुंजी और मूल्य के अलावा, "accumulate" नामक एक कॉलम है। उन पंक्तियों के लिए जहां संचय सत्य है, मान अल्पविराम से अलग किए गए स्ट्रिंग के रूप में संचित करने के लिए हैं। अन्य पंक्तियों के लिए, मान एकल-मूल्यवान होते हैं।

demo=# CREATE TABLE kv2 (
demo(#     key text PRIMARY KEY,
demo(#     accumulate boolean NOT NULL DEFAULT false,
demo(#     value text
demo(# );
CREATE TABLE
demo=# INSERT INTO kv2 VAlUES
demo-#     ('port', false, '5432'),
demo-#     ('listen', true, NULL);
INSERT 0 2
demo=# SELECT * FROM kv2;
  key   | accumulate | value
--------+------------+-------
 port   | f          | 5432
 listen | t          |
(2 rows)

WHERE क्लॉज का उपयोग या तो "मान" कॉलम को अधिलेखित करने के लिए किया जा सकता है, या "संचय" के मूल्य के आधार पर इसमें जोड़ा जा सकता है:

demo=# INSERT INTO kv2 AS t (key, value) VALUES ('port', '3306')
demo-# ON CONFLICT (key) DO UPDATE SET value = concat_ws(',', t.value, EXCLUDED.value)
demo-# WHERE t.accumulate;
INSERT 0 0
demo=# INSERT INTO kv2 AS t (key, value) VALUES ('listen', '127.0.0.1')
demo-# ON CONFLICT (key) DO UPDATE SET value = concat_ws(',', t.value, EXCLUDED.value)
demo-# WHERE t.accumulate;
INSERT 0 1
demo=# INSERT INTO kv2 AS t (key, value) VALUES ('listen', '10.0.10.1')
demo-# ON CONFLICT (key) DO UPDATE SET value = concat_ws(',', t.value, EXCLUDED.value)
demo-# WHERE t.accumulate;
INSERT 0 1
demo=# SELECT * FROM kv2;
  key   | accumulate |        value
--------+------------+---------------------
 port   | f          | 5432
 listen | t          | 127.0.0.1,10.0.10.1
(2 rows)

पहले स्टेटमेंट ने '3306' के मान को 'पोर्ट' में संचित नहीं किया क्योंकि उस पंक्ति के लिए 'accumulate' बंद था। अगले दो कथनों ने '127.0.0.1' और '10.0.10.1' को 'सुनो' के मान में जोड़ा, क्योंकि 'accumulate' सच था।

जेनरेट किए गए मान लौटाना

डालने के दौरान PostgreSQL द्वारा उत्पन्न मान, जैसे डिफ़ॉल्ट मान या स्वतः वृद्धि किए गए सीरियल मान RETURNING का उपयोग करके वापस किए जा सकते हैं INSERT कथन का खंड।

मान लें कि आपको किसी तालिका में पंक्तियों के लिए कुंजियों के रूप में यादृच्छिक UUIDs उत्पन्न करने की आवश्यकता है। आप पोस्टग्रेएसक्यूएल को यूयूआईडी बनाने का काम करने दे सकते हैं और इसे इस तरह से आपके लिए जेनरेटेड वैल्यू वापस कर सकते हैं:

demo=# INSERT INTO kv (key, value) VALUES (gen_random_uuid(), 'foo') RETURNING key;
                 key
--------------------------------------
 d93ceaa5-30a8-4285-83c5-7defa79e2f90
(1 row)

INSERT 0 1
demo=# INSERT INTO kv (key, value) VALUES (gen_random_uuid(), 'bar') RETURNING key;
                 key
--------------------------------------
 caf9c5d9-9a79-4b26-877f-a75a083b0c79
(1 row)

INSERT 0 1
demo=# SELECT * FROM kv;
                 key                  | value
--------------------------------------+-------
 d93ceaa5-30a8-4285-83c5-7defa79e2f90 | foo
 caf9c5d9-9a79-4b26-877f-a75a083b0c79 | bar
(2 rows)

CTE क्लॉज के साथ पंक्तियों को मूव करना

आप WITH . का उपयोग करके INSERT के साथ तालिकाओं के बीच पंक्तियों को भी स्थानांतरित कर सकते हैं खंड। यहां विभिन्न वर्षों के लिए टूडू सूचियों वाली दो तालिकाएं हैं।

demo=# SELECT * FROM todos_2018;
      what      | done
----------------+------
 thing to do #1 | t
 thing to do #2 | t
 thing to do #3 | f
(3 rows)

demo=# SELECT * FROM todos_2019;
 what | done
------+------
(0 rows)

टूडू आइटम को स्थानांतरित करने के लिए जो 2018 से 2019 में अभी तक पूर्ण नहीं हुए हैं, आप मूल रूप से 2018 तालिका से ऐसी पंक्तियों को हटा सकते हैं और उन्हें एक शॉट में 2019 तालिका में सम्मिलित कर सकते हैं:

demo=# WITH items AS (
demo(#     DELETE FROM todos_2018
demo(#     WHERE NOT done
demo(#     RETURNING *
demo(# )
demo-# INSERT INTO todos_2019 SELECT * FROM items;
INSERT 0 1
demo=# SELECT * FROM todos_2018;
      what      | done
----------------+------
 thing to do #1 | t
 thing to do #2 | t
(2 rows)

demo=# SELECT * FROM todos_2019;
      what      | done
----------------+------
 thing to do #3 | f
(1 row)

स्मार्ट छोटे INSERT कथन के बारे में अधिक जानने के लिए, दस्तावेज़ीकरण और प्रयोग देखें!


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. पोस्टग्रेज में लॉक रखने वाली क्वेरी का पता कैसे लगाएं?

  2. एसक्यूएल:उन रिकॉर्ड्स का चयन करें जहां सभी जुड़े हुए रिकॉर्ड कुछ शर्तों को पूरा करते हैं

  3. रिमोट मशीन पर डंप को पुनर्स्थापित करें

  4. टाइमस्टैम्प से मिलीसेकंड भाग छोड़ें

  5. PostgreSQL 9.2 में तालिका को लॉक किए बिना डेटाबेस पंक्तियों को अद्यतन करना