PostgreSQL में एक अस्थायी फ़ंक्शन कैसे बनाएं?


83

मुझे डेटाबेस में एक लूप निष्पादित करना है। यह केवल एक बार की आवश्यकता है। फंक्शन को अंजाम देने के बाद, अब मैं फंक्शन छोड़ रहा हूं।

क्या अस्थायी / डिस्पोजेबल कार्यों को बनाने के लिए कोई अच्छा तरीका है?

जवाबों:


115

मुझे यह जानने की ज़रूरत थी कि मैं जो पटकथा लिख ​​रहा था, उसमें कई बार कैसे उपयोग किया जाए। पता चलता है कि आप pg_temp स्कीमा का उपयोग करके एक अस्थायी फ़ंक्शन बना सकते हैं। यह एक स्कीमा है जो आपके कनेक्शन की मांग पर बनाई गई है और जहां अस्थायी टेबल संग्रहीत हैं। जब आपका कनेक्शन बंद हो जाता है या समाप्त हो जाता है तो यह स्कीमा गिरा दिया जाता है। यदि आप इस स्कीमा पर कोई फ़ंक्शन बनाते हैं, तो स्कीमा स्वचालित रूप से बनाई जाएगी। इसलिए,

create function pg_temp.testfunc() returns text as 
$$ select 'hello'::text $$ language sql;

एक ऐसा फ़ंक्शन होगा जो आपके कनेक्शन के चारों ओर चिपक जाने तक चिपका रहेगा। ड्रॉप कमांड को कॉल करने की आवश्यकता नहीं है।


62

@ Crowmagnumb के जवाब में स्मार्ट ट्रिक के लिए कुछ अतिरिक्त नोट्स :

  • ट्रोजन घोड़ों को रोकने के लिए टॉम लेन के अनुसार , फ़ंक्शन को हर समय स्कीमा-योग्य होना चाहिए , भले ही pg_tempवह search_path(जैसे कि डिफ़ॉल्ट रूप से) हो।
CREATE FUNCTION pg_temp.f_inc(int)
  RETURNS int AS 'SELECT $1 + 1' LANGUAGE sql IMMUTABLE;

SELECT pg_temp.f_inc(42);
f_inc
-----
43
  • अस्थायी स्कीमा में बनाया गया एक फ़ंक्शन केवल उसी सत्र के अंदर दिखाई देता है (जैसे अस्थायी तालिकाओं)। यह अन्य सभी सत्रों के लिए अदृश्य है (समान भूमिका के लिए भी)। आप एक ही सत्र के बाद फ़ंक्शन को एक अलग भूमिका के रूप में एक्सेस कर सकते हैंSET ROLE

  • आप इस "अस्थायी" फ़ंक्शन के आधार पर एक कार्यात्मक सूचकांक भी बना सकते हैं:

    CREATE INDEX foo_idx ON tbl (pg_temp.f_inc(id));
    

    जिससे एक गैर-अस्थायी तालिका पर एक अस्थायी फ़ंक्शन का उपयोग करके एक सादा सूचकांक बनाया जा सकता है। ऐसा सूचकांक सभी सत्रों के लिए दिखाई देगा, लेकिन फिर भी केवल निर्माण सत्र के लिए ही मान्य होगा। क्वेरी प्लानर एक कार्यात्मक सूचकांक का उपयोग नहीं करेगा, जहां क्वेरी में अभिव्यक्ति को दोहराया नहीं जाता है। अभी भी थोड़ी गंदी चाल है। सत्र बंद होने पर यह स्वचालित रूप से हटा दिया जाएगा - एक निर्भर वस्तु के रूप में। ऐसा लगता है कि इसे बिल्कुल भी अनुमति नहीं दी जानी चाहिए ...


यदि आपको केवल किसी फ़ंक्शन को बार-बार निष्पादित करने की आवश्यकता है और आपको SQL की आवश्यकता है, तो इसके बजाय एक तैयार कथन पर विचार करें । यह एक अस्थायी SQL फ़ंक्शन की तरह काम करता है जो सत्र के अंत में मर जाता है। एक ही बात नहीं है, हालांकि, और केवल खुद के साथ ही इस्तेमाल किया जा सकता है EXECUTE, किसी अन्य क्वेरी के अंदर नेस्टेड नहीं। उदाहरण:

PREPARE upd_tbl AS
UPDATE tbl t SET set_name = $2 WHERE tbl_id = $1;

कॉल करें:

EXECUTE upd_tbl(123, 'foo_name');

विवरण:


31

यदि आप संस्करण 9.0 का उपयोग कर रहे हैं, तो आप इसे नए डीओ स्टेटमेंट के साथ कर सकते हैं:

http://www.postgresql.org/docs/current/static/sql-do.html

पिछले संस्करणों के साथ, आपको फ़ंक्शन बनाना होगा, इसे कॉल करना होगा, और इसे फिर से ड्रॉप करना होगा।


4
... यह टर्मिनल पर स्क्रिप्टिंग के लिए उपयोगी है, लेकिन आप इसे फिर से नहीं कह सकते हैं, जैसे "अननोनियस फ़ंक्शन" (या लैम्ब्डा), इसलिए डीओ स्टैटिमेंट "अस्थायी फ़ंक्शन" के रूप में इतना उपयोगी नहीं है।
पीटर क्रूस

@PeterKrauss: यदि आप इसे फिर से कॉल करना चाहते हैं, तो आपको एक वास्तविक फ़ंक्शन बनाने की आवश्यकता है।
a_horse_with_no_name

बेशक मेरे a_hourse :-) मैं केवल "अस्थायी" को लागू करने के लिए सैद्धांतिक रास्ता दिखा रहा था ... यही कारण है कि मुख्य प्रश्न के लिए बेहतर उत्तर (पोस्टग्रेक्यूएल के साथ संभव) है, है pg_temp.foo()। मुझे समझ नहीं आ रहा है कि क्यों, (?) आज, 2014, लुआ के रूप में इतने सरल और इतने तेज़ उदाहरणों के साथ , एसक्यूएल डीएमएल भाषाएँ लैम्बडा फ़ंक्शंस (!) की पेशकश नहीं कर सकती हैं ।
पीटर क्रस

7
इसके अलावा, DOबयानों में इनपुट पैरामीटर नहीं हो सकते हैं और फ़ंक्शन के विपरीत परिणाम नहीं लौट सकते हैं।
डैनियल वेरिटे

2
यदि यह वापस नहीं आता है, तो क्या हमें इसे "फ़ंक्शन" कहना चाहिए?
आंद्रेकर

-4

तदर्थ प्रक्रियाओं के लिए, कर्सर बहुत बुरे नहीं हैं। वे हालांकि productino उपयोग के लिए भी अक्षम हैं।

वे आपको आसानी से db में sql परिणामों पर लूप देंगे।


6
आपको क्या लगता है कि PostgreSQL में कर्सर अक्षम हैं?
फ्रैंक हाइकेन

2
लूप होने पर कर्सर डेटाबेस कनेक्शन को पकड़ लेते हैं। सैकड़ों लंबे समय से चल रहे कर्सर के साथ एक वेब पेज कनेक्शन को भूखा रखेगा और साइट / डेटाबेस को अपने घुटनों पर लाएगा।
बायरन व्हिटलॉक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.