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

एक विशिष्ट स्ट्रिंग से शुरू होने वाले कई कॉलम अपडेट करें

इसके लिए आपको डायनेमिक SQL चाहिए। इसलिए आपको संभावित SQL इंजेक्शन से निपटने के लिए तैयार रहना चाहिए।

मूल क्वेरी

आवश्यक डीएमएल कमांड उत्पन्न करने के लिए मूल क्वेरी इस तरह दिख सकती है:

SELECT format('UPDATE tbl SET (%s) = (%s)'
               ,string_agg (quote_ident(attname), ', ')
               ,string_agg ('NULL', ', ')
             )
FROM   pg_attribute
WHERE  attrelid = 'tbl'::regclass
AND    NOT attisdropped 
AND    attnum > 0
AND    attname ~~ 'foo_%';

रिटर्न:

UPDATE tbl SET (foo_a, foo_b, foo_c) = (NULL, NULL, NULL);
  • मैं "कॉलम-लिस्ट सिंटैक्स का उपयोग करता हूं मजबूत> "UPDATE का कोड को छोटा करने और कार्य को सरल बनाने के लिए।

  • मैं सिस्टम कैटलॉग को क्वेरी करता हूं सूचना स्कीमा के बजाय क्योंकि बाद वाला, मानकीकृत होने और प्रमुख संस्करणों में पोर्टेबल होने की गारंटी होने के बावजूद, कुख्यात रूप से धीमा और कभी-कभी बोझिल भी होता है। इसके पक्ष और विपक्ष हैं, हमने यहां SO पर कई बार इस पर चर्चा की है। अधिक जानकारी के लिए कीवर्ड खोजें।

  • quote_ident() कॉलम नामों के लिए SQL-इंजेक्शन को रोकता है और किसी भी . के लिए भी आवश्यक है गैर-मानक कॉलम नाम।

  • आपने अपने पोस्टग्रेस संस्करण का उल्लेख करने की उपेक्षा की। समग्र कार्य string_agg() 9.0+ की आवश्यकता है।

PL/pgSQL फ़ंक्शन के साथ पूर्ण स्वचालन

CREATE OR REPLACE FUNCTION f_update_cols(_tbl regclass, _col_pattern text
                                        , OUT row_ct int, OUT col_ct int)
  RETURNS record AS
$func$
DECLARE
   _sql text;
BEGIN
   SELECT format('UPDATE tbl SET (%s) = (%s)'
                 ,string_agg (quote_ident(attname), ', ')
                 ,string_agg ('NULL', ', ')
                )
         ,count(*)::int
   INTO   _sql, col_ct
   FROM   pg_attribute
   WHERE  attrelid = _tbl
   AND    NOT attisdropped         -- no dropped columns
   AND    attnum > 0               -- no system columns
   AND    attname ~~ _col_pattern; -- only columns matching pattern

   -- RAISE NOTICE '%', _sql;      -- output generated SQL for debugging
   EXECUTE _sql;

   GET DIAGNOSTICS row_ct = ROW_COUNT;
END
$func$  LANGUAGE plpgsql;

COMMENT ON FUNCTION f_update_cols(regclass, text)
 IS 'Updates all columns of table _tbl ($1)
that match _col_pattern ($2) in a LIKE expression.
Returns the count of columns (col_ct) and rows (row_ct) affected.';

कॉल करें:

SELECT * FROM f_update_cols('myschema.tbl', 'foo%');
  • फ़ंक्शन को और अधिक व्यावहारिक बनाने के लिए, यह टिप्पणी में वर्णित जानकारी देता है। परिणाम स्थिति प्राप्त करने के बारे में अधिक जानकारी मैनुअल में plpgsql में।

  • मैं वेरिएबल _sql . का उपयोग करता हूं क्वेरी स्ट्रिंग को होल्ड करने के लिए, ताकि मैं पाए गए स्तंभों की संख्या एकत्र कर सकूं (col_ct ) एक ही प्रश्न में।

  • वस्तु पहचानकर्ता प्रकार regclass तालिका नाम के लिए स्वचालित रूप से SQL इंजेक्शन (और गैर-मानक नामों को साफ करने) से बचने का सबसे कारगर तरीका है। आप स्कीमा-योग्य तालिका नामों का उपयोग कर सकते हैं अस्पष्टताओं से बचने के लिए। मैं ऐसा करने की सलाह दूंगा यदि आपके डीबी में एकाधिक स्कीमा हैं! इस संबंधित प्रश्न में अधिक विवरण:
    तालिका नाम PostgreSQL फ़ंक्शन पैरामीटर के रूप में

-> SQLfiddle डेमो



  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 व्यू के लिए जहां पैरामीटर पास करें?

  2. SQL में LOOP को शामिल करना

  3. संयोजन मतभेदों को पोस्टग्रेज करता है। ओएसएक्स वी उबंटू

  4. एकाधिक पंक्तियों को सम्मिलित करते समय डुप्लिकेट के साथ क्या होता है?

  5. क्या कोई समझा सकता है कि पोस्टग्रेस्क्ल-क्लाइंट क्या है और यह पोस्टग्रेस्क्ल कोर पैकेज के साथ कैसे इंटरैक्ट करता है?