सुधार की गुंजाइश है:
CREATE OR REPLACE FUNCTION report_get_countries_new (starts_with text
, ends_with text = NULL)
RETURNS SETOF lookups.countries AS
$func$
DECLARE
sql text := 'SELECT * FROM lookups.countries WHERE country_name >= $1';
BEGIN
IF ends_with IS NOT NULL THEN
sql := sql || ' AND country_name <= $2';
END IF;
RETURN QUERY EXECUTE sql
USING starts_with, ends_with;
END
$func$ LANGUAGE plpgsql;
-- the rest is default settings
प्रमुख बिंदु
-
PostgreSQL 8.4 ने
<ब्लॉककोट>USING
. की शुरुआत कीEXECUTE
. के लिए क्लॉज , जो कई कारणों से उपयोगी है। मैनुअल में पुनर्कथन:कमांड स्ट्रिंग पैरामीटर मानों का उपयोग कर सकती है, जिन्हें कमांड में
$1, $2
. के रूप में संदर्भित किया जाता है , आदि। ये प्रतीकUSING
. में दिए गए मानों को संदर्भित करते हैं खंड। टेक्स्ट के रूप में कमांड स्ट्रिंग में डेटा वैल्यू डालने के लिए यह विधि अक्सर बेहतर होती है:यह मूल्यों को टेक्स्ट और बैक में कनवर्ट करने के रन-टाइम ओवरहेड से बचाती है, और यह एसक्यूएल-इंजेक्शन हमलों के लिए बहुत कम प्रवण होती है क्योंकि उद्धरण या भागने की कोई आवश्यकता नहीं होती है।पी>IOW, यह पैरामीटर के टेक्स्ट प्रस्तुतिकरण के साथ क्वेरी स्ट्रिंग बनाने की तुलना में अधिक सुरक्षित और तेज़ है, भले ही
quote_literal()
से सैनिटाइज़ किया गया हो। .
ध्यान दें कि$1, $2
क्वेरी स्ट्रिंग मेंUSING
. में दिए गए मानों को देखें खंड, नहीं फ़ंक्शन पैरामीटर के लिए। -
जब आप
SELECT * FROM lookups.countries
लौटते हैं , आपRETURN
. को सरल बना सकते हैं प्रदर्शित की तरह घोषणा:RETURNS SETOF lookups.countries
PostgreSQL में प्रत्येक तालिका के लिए स्वचालित रूप से परिभाषित एक समग्र प्रकार होता है। इसका इस्तेमाल करें। प्रभाव यह है कि फ़ंक्शन प्रकार पर निर्भर करता है और यदि आप तालिका को बदलने का प्रयास करते हैं तो आपको एक त्रुटि संदेश मिलता है। ऐसी स्थिति में फंक्शन को ड्रॉप और रीक्रिएट करें।
यह वांछनीय हो सकता है या नहीं भी हो सकता है - आम तौर पर यह है! यदि आप टेबल बदलते हैं तो आप साइड इफेक्ट के बारे में जागरूक होना चाहते हैं। जिस तरह से आपके पास है, आपका कार्य चुपचाप टूट जाएगा और इसके अगले कॉल पर अपवाद उठाएगा।
-
यदि आप एक स्पष्ट डिफ़ॉल्ट . प्रदान करते हैं प्रदर्शन की तरह घोषणा में दूसरे पैरामीटर के लिए, यदि आप
ends_with
के साथ ऊपरी सीमा सेट नहीं करना चाहते हैं तो आप कॉल को सरल बना सकते हैं (लेकिन ऐसा करने की आवश्यकता नहीं है) ।SELECT * FROM report_get_countries_new('Zaire');
इसके बजाय:
SELECT * FROM report_get_countries_new('Zaire', NULL);
इस संदर्भ में फ़ंक्शन ओवरलोडिंग से अवगत रहें।
-
भाषा का नाम उद्धृत न करें
भले ही वह सहन किया गया हो (अभी के लिए)। यह एक पहचानकर्ता है।'plpgsql' -
आप घोषणा के समय एक वैरिएबल असाइन कर सकते हैं। एक अतिरिक्त कदम बचाता है।
-
पैरामीटर्स को हेडर में नाम दिया गया है। निरर्थक पंक्तियों को छोड़ें:
starts_with ALIAS FOR $1; ends_with ALIAS FOR $2;