मैं इसे इस तरह से करूंगा:
CREATE OR REPLACE FUNCTION list(
_category varchar(100)
, _limit int
, _offset int
, _order_by varchar(100)
, _order_asc_desc text = 'ASC') -- last param with default value
RETURNS TABLE(id int, name varchar, clientname varchar, totalcount bigint)
LANGUAGE plpgsql AS
$func$
DECLARE
_empty text := '';
BEGIN
-- Assert valid _order_asc_desc
IF upper(_order_asc_desc) IN ('ASC', 'DESC', 'ASCENDING', 'DESCENDING') THEN
-- proceed
ELSE
RAISE EXCEPTION 'Unexpected value for parameter _order_asc_desc.
Allowed: ASC, DESC, ASCENDING, DESCENDING. Default: ASC';
END IF;
RETURN QUERY EXECUTE format(
'SELECT id, name, clientname, count(*) OVER() AS full_count
FROM design_list
WHERE ($1 = $2 OR category ILIKE $1)
ORDER BY %I %s
LIMIT %s
OFFSET %s'
, _order_by, _order_asc_desc, _limit, _offset)
USING _category, _empty;
END
$func$;
मुख्य विशेषता:format()
अपनी क्वेरी स्ट्रिंग को सुरक्षित और सुंदर ढंग से संयोजित करने के लिए। संबंधित:
- इन्सर्ट के साथ ट्रिगर फ़ंक्शन में गतिशील तालिका का नाम
- EXECUTE के लिए format() में पूर्णांक चर के लिए प्रारूप विनिर्देशक?
ASC / DESC (या ASCENDING / DESCENDING ) निश्चित कुंजी शब्द हैं। मैंने मैन्युअल जांच जोड़ी (IF ... ) और बाद में एक साधारण %s . के साथ संयोजित करें . वह एक है कानूनी इनपुट का दावा करने का तरीका। सुविधा के लिए, मैंने अनपेक्षित इनपुट और पैरामीटर डिफ़ॉल्ट के लिए एक त्रुटि संदेश जोड़ा है, इसलिए फ़ंक्शन डिफ़ॉल्ट रूप से ASC पर है यदि कॉल में अंतिम पैरामीटर छोड़ा गया है। संबंधित:
- PL में वैकल्पिक तर्क /pgSQL फ़ंक्शन
- त्रुटि:एक के बाद एक डिफ़ॉल्ट मान वाले इनपुट पैरामीटर पोस्टग्रेज़ में भी डिफ़ॉल्ट होने चाहिए
संबोधित करना टिप्पणी
, मैं संयोजित करता हूं _limit और _offset सीधे, इसलिए क्वेरी पहले से ही उन पैरामीटर के साथ नियोजित है।
_limit और _offset integer हैं पैरामीटर, इसलिए हम सादे %s . का उपयोग कर सकते हैं एसक्यूएल इंजेक्शन के खतरे के बिना। संयोजन करने से पहले आप उचित मूल्यों (नकारात्मक मूल्यों और बहुत अधिक मूल्यों को छोड़कर) पर जोर देना चाह सकते हैं ...
-
एक सुसंगत नामकरण सम्मेलन का प्रयोग करें। मैंने सभी पैरामीटर और वैरिएबल को अंडरस्कोर
_. के साथ प्रीफ़िक्स किया है , न केवल कुछ । -
EXECUTE. के अंदर तालिका योग्यता का उपयोग नहीं कर रहा है , क्योंकि इसमें केवल एक ही तालिका शामिल है औरEXECUTEइसका अलग दायरा है। -
मैंने स्पष्ट करने के लिए कुछ मापदंडों का नाम बदल दिया।
_order_by_sort_by. के बजाय;_order_asc_desc_order. के बजाय ।