इसके लिए आपको डायनेमिक 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 फ़ंक्शन पैरामीटर के रूप में