सेटअप
आप मेरे संबंधित उत्तर में उल्लिखित समान ट्रिगर फ़ंक्शन का उपयोग करके ट्रिगर्स (बार-बार?) बनाना चाहते हैं dba.SE . एकाधिक . बनाने के लिए आपको ट्रिगर फ़ंक्शन में मान पास करने होंगे एकाधिक . के साथ पंक्तियाँ स्तंभ मान, इसलिए द्वि-आयामी सरणी। (लेकिन हम किसी भी . के साथ काम कर सकते हैं स्पष्ट रूप से परिभाषित स्ट्रिंग!)
PL/pgSQL ट्रिगर फ़ंक्शन (ट्रिगरिंग पंक्ति के कॉलम मानों के अलावा) को मान पास करने का एकमात्र तरीका text
है पैरामीटर, जो फ़ंक्शन के अंदर 0- के रूप में पहुंच योग्य हैं। विशेष सरणी चर में पाठ की आधारित सरणी TG_ARGV[]
. आप पैरामीटर की एक चर संख्या पास कर सकते हैं, लेकिन हमने पहले आपके 2-आयामी सरणी का प्रतिनिधित्व करने वाले एकल स्ट्रिंग अक्षर पर चर्चा की थी।
इनपुट हस्ताक्षरित पूर्णांक . के साथ 2-आयामी पायथन सरणी से आता है संख्याएँ, जो पोस्टग्रेज़ प्रकार integer
. में फ़िट हो जाती हैं . Postgres प्रकार bigint
. का उपयोग करें अहस्ताक्षरित पूर्णांक संख्याओं को कवर करने के लिए, जैसा टिप्पणी की
।
पायथन में पाठ का प्रतिनिधित्व इस तरह दिखता है:
[[1,2],[3,4]]
Postgres सरणी शाब्दिक के लिए सिंटैक्स:
{{1,2},{3,4}}
और आप प्रक्रिया को स्वचालित करना चाहते हैं।
पूर्ण स्वचालन
आप CREATE TRIGGER
. के लिए स्ट्रिंग को जोड़ सकते हैं अपने क्लाइंट में स्टेटमेंट या आप सर्वर-साइड फ़ंक्शन में लॉजिक को जारी रख सकते हैं और केवल पैरामीटर पास कर सकते हैं।
तालिका नाम और ट्रिगर फ़ंक्शन को पास की गई स्ट्रिंग लेते हुए एक उदाहरण फ़ंक्शन का प्रदर्शन करना। ट्रिगर फ़ंक्शन insaft_function()
dba.SE पर आपके पिछले प्रश्न में परिभाषित किया गया है
।
CREATE OR REPLACE FUNCTION f_create_my_trigger(_tbl regclass, _arg0 text)
RETURNS void
LANGUAGE plpgsql AS
$func$
BEGIN
EXECUTE format($$
DROP TRIGGER IF EXISTS insaft_%1$s_ids ON %1$s;
CREATE TRIGGER insaft_%1$s_ids
AFTER INSERT ON %1$s
FOR EACH ROW EXECUTE PROCEDURE insaft_function(%2$L)$$
, _tbl
, translate(_arg0, '[]', '{}')
);
END
$func$;
कॉल करें:
SELECT f_create_my_trigger('measurements', '[[1,2],[3,4]]');
या:
SELECT f_create_my_trigger('some_other_table', '{{5,6},{7,8}}');
db<>fiddle यहां
पुराना sqlfiddle
उप>
अब आप या तो [[1,2],[3,4]]
. पास कर सकते हैं (वर्ग कोष्ठक के साथ) या {{1,2},{3,4}}
(घुंघराले ब्रेसिज़ के साथ)। दोनों एक ही काम करते हैं। translate(_arg0, '[]', '{}'
पहले को दूसरे रूप में बदल देता है।
यह फ़ंक्शन नया बनाने से पहले, उसी नाम के ट्रिगर को छोड़ देता है यदि यह मौजूद है। आप इस लाइन को छोड़ना या रखना चाह सकते हैं:
DROP TRIGGER IF EXISTS insaft_%1$s_ids ON %1$s;
यह कॉलिंग डीबी भूमिका के विशेषाधिकारों के साथ चलता है। जरूरत पड़ने पर आप इसे सुपरयुसर (या किसी अन्य) विशेषाधिकारों के साथ चला सकते हैं। देखें:
इसे हासिल करने के कई तरीके हैं। यह सटीक आवश्यकताओं पर निर्भर करता है।
व्याख्या करना format()
format()
और डेटा प्रकार regclass
डीडीएल कमांड को सुरक्षित रूप से संयोजित करने और एसक्यूएल इंजेक्शन को असंभव बनाने में मदद करें। देखें:
पहला तर्क "प्रारूप स्ट्रिंग" है, इसके बाद तर्कों को स्ट्रिंग में एम्बेड किया जाना है। मैं डॉलर-कोटिंग
का उपयोग करता हूं , जो उदाहरण के लिए कड़ाई से आवश्यक नहीं है, लेकिन आम तौर पर सिंगल-कोट्स वाले लंबे स्ट्रिंग्स को संयोजित करने के लिए एक अच्छा विचार है:$$DROP TRIGGER ... $$
format()
C फ़ंक्शन sprintf
. के अनुरूप बनाया गया है . %1$s
format()
समारोह। इसका मतलब है कि पहला (1$
) तर्क के बाद प्रारूप स्ट्रिंग को उद्धृत स्ट्रिंग . के रूप में सम्मिलित किया गया है (%s
), इसलिए:%1$s
. प्रारूप का पहला तर्क है _tbl
उदाहरण में - regclass
पैरामीटर को कानूनी पहचानकर्ता के रूप में स्वचालित रूप से प्रस्तुत किया जाता है, यदि आवश्यक हो तो डबल-उद्धृत किया जाता है, इसलिए format()
अधिक नहीं करना है। इसलिए सिर्फ %s
, नहीं %I
(पहचानकर्ता)। विवरण के लिए ऊपर दिए गए लिंक किए गए उत्तर को पढ़ें।
उपयोग में अन्य प्रारूप विनिर्देशक %2$L
है :दूसरा तर्क उद्धृत स्ट्रिंग शाब्दिक . के रूप में ।
अगर आप format()
. में नए हैं , समझने के लिए इन सरल उदाहरणों के साथ खेलें:
SELECT format('input -->|%s|<-- here', '[1,2]')
, format('input -->|%s|<-- here', translate('[1,2]', '[]', '{}'))
, format('input -->|%L|<-- here', translate('[1,2]', '[]', '{}'))
, format('input -->|%I|<-- here', translate('[1,2]', '[]', '{}'));
और मैनुअल पढ़ें ।