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

निष्पादित करें ... में ... पीएल/पीजीएसक्यूएल में कथन का उपयोग रिकॉर्ड में निष्पादित नहीं हो सकता है?

आपके पोस्ट किए गए उत्तर का सरल विकल्प। बहुत बेहतर प्रदर्शन करना चाहिए।

यह फ़ंक्शन किसी दी गई तालिका से एक पंक्ति पुनर्प्राप्त करता है (in_table_name ) और प्राथमिक कुंजी मान (in_row_pk ), और इसे उसी तालिका में नई पंक्ति के रूप में सम्मिलित करता है, कुछ मानों को बदल दिया जाता है (in_override_values ) डिफ़ॉल्ट रूप से नया प्राथमिक कुंजी मान लौटाया जाता है (pk_new )।

CREATE OR REPLACE FUNCTION f_clone_row(in_table_name regclass
                                     , in_row_pk int
                                     , in_override_values hstore
                                     , OUT pk_new int) AS
$func$
DECLARE
   _pk   text;  -- name of PK column
   _cols text;  -- list of names of other columns
BEGIN

-- Get name of PK column
SELECT INTO _pk  a.attname
FROM   pg_catalog.pg_index     i
JOIN   pg_catalog.pg_attribute a ON a.attrelid = i.indrelid
                                AND a.attnum   = i.indkey[0]  -- 1 PK col!
WHERE  i.indrelid = 't'::regclass
AND    i.indisprimary;

-- Get list of columns excluding PK column
_cols := array_to_string(ARRAY(
      SELECT quote_ident(attname)
      FROM   pg_catalog.pg_attribute
      WHERE  attrelid = in_table_name -- regclass used as OID
      AND    attnum > 0               -- exclude system columns
      AND    attisdropped = FALSE     -- exclude dropped columns
      AND    attname <> _pk           -- exclude PK column
      ), ',');

-- INSERT cloned row with override values, returning new PK
EXECUTE format('
   INSERT INTO %1$I (%2$s)
   SELECT %2$s
   FROM  (SELECT (t #= $1).* FROM %1$I t WHERE %3$I = $2) x
   RETURNING %3$I'
 , in_table_name, _cols, _pk)
USING   in_override_values, in_row_pk -- use override values directly
INTO    pk_new;                       -- return new pk directly

END
$func$ LANGUAGE plpgsql;

कॉल करें:

SELECT f_clone_row('t', 1, '"col1"=>"foo_new","col2"=>"bar_new"'::hstore);

SQL Fiddle.

  • regclass का इस्तेमाल करें इनपुट पैरामीटर प्रकार के रूप में, इसलिए शुरू करने के लिए केवल मान्य तालिका नामों का उपयोग किया जा सकता है और SQL इंजेक्शन को खारिज कर दिया जाता है। यदि आपको एक अवैध तालिका नाम प्रदान करना चाहिए, तो फ़ंक्शन पहले और अधिक शानदार ढंग से विफल हो जाता है।

  • एक आउट का प्रयोग करें पैरामीटर (pk_new ) वाक्य रचना को सरल बनाने के लिए।

  • प्राथमिक कुंजी के लिए मैन्युअल रूप से अगला मान निकालने की आवश्यकता नहीं है। यह स्वचालित रूप से डाला जाता है और तथ्य के बाद वापस आ जाता है। यह न केवल सरल और तेज़ है, आप व्यर्थ या आउट-ऑफ-ऑर्डर अनुक्रम संख्याओं से भी बचते हैं।

  • format() गतिशील क्वेरी स्ट्रिंग की असेंबली को सरल बनाने और इसे कम त्रुटि-प्रवण बनाने के लिए। ध्यान दें कि मैं क्रमशः पहचानकर्ताओं और स्ट्रिंग्स के लिए स्थितीय मापदंडों का उपयोग कैसे करता हूं।

  • मैं आपकी अंतर्निहित धारणा . पर आधारित हूं अनुमति दी गई तालिकाओं में एक एक डिफ़ॉल्ट स्तंभ के साथ पूर्णांक प्रकार का एकल प्राथमिक कुंजी स्तंभ होता है . आमतौर पर serial कॉलम।

  • फ़ंक्शन का मुख्य तत्व अंतिम है INSERT :

    • #= ऑपरेटर उप-चयन में और परिणामी पंक्ति को तुरंत विघटित करें।
    • तब आप मुख्य SELECT . में केवल प्रासंगिक कॉलम चुन सकते हैं ।
    • Postgres को PK के लिए डिफ़ॉल्ट मान निर्दिष्ट करने दें और इसे रिटर्निंग के साथ वापस प्राप्त करें खंड।
    • लौटा हुआ मान OUT में लिखें सीधे पैरामीटर।
    • सब कुछ एक SQL कमांड में किया जाता है, जो आमतौर पर सबसे तेज़ होता है।


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQLAlchemy का उपयोग करके PostgreSQL सरणी को अपडेट करें

  2. वॉल्यूम का उपयोग करके डॉक किए गए पोस्टग्रेज डेटाबेस में डेटा को कैसे बनाए रखें

  3. गो स्क्रैच कंटेनर और पीजी कंटेनर के बीच एसएसएल कनेक्शन की समस्या। कैसे हल करें?

  4. PostgreSQL 9.0 और 9.1 . के बीच एनम प्रकार के शाब्दिक क्रम में अंतर

  5. टेक्स्ट सरणी में जेसन सरणी कैसे डालें?