2012-05-17 11 views
11

मुझे एक ऐसा फ़ंक्शन बनाना होगा जो एक क्वेरी चलाएगा और तालिका के नाम के साथ परिणामों को वापस कर देगा और कॉलम नाम को फ़ंक्शन को दिए गए ऑग्रेमेंट्स के साथ वापस कर देगा। मेरे पास वर्तमान में यह है:पोस्टग्रेज़ डायनामिक क्वेरी फंक्शन

CREATE OR REPLACE FUNCTION qa_scf(tname character varying, cname character varying) 
RETURNS SETOF INT AS 
$BODY$ 
BEGIN 
RETURN QUERY SELECT * FROM tname WHERE cname !='AK' AND cname!='CK'; 
END; 
$BODY$ 
LANGUAGE plpgsql VOLATILE 
COST 100 
ROWS 1000; 

यह मुझे चलाने पर त्रुटि "संबंध 'tname' des मौजूद नहीं है" देता है। मैं पोस्टग्रेज़ के लिए काम करने के लिए नया हूं, इसलिए किसी भी मदद की सराहना की जाती है। मुझे लगता है कि रिटर्न int गलत है, लेकिन मुझे नहीं पता कि यह पंक्तियों के लिए सभी कॉलम वापस करने के लिए और क्या करना है। धन्यवाद!

उत्तर

17

आप इस तरह के पहचानकर्ता के स्थान पर एक चर का उपयोग नहीं कर सकते हैं। आपको गतिशील प्रश्नों के साथ ऐसा करने की आवश्यकता है।

EXECUTE 'SELECT * FROM ' || quote_ident(tname) 
     || ' WHERE ' || quote_ident(cname) || ' NOT IN (''AK'',''CK'');' 
INTO result_var; 

आप PostgreSQL 9.1 उपयोग कर रहे हैं या इसके बाद, आप the format() function जो इस स्ट्रिंग का निर्माण बहुत आसान बना देता है का उपयोग कर सकते: यह कुछ इस तरह दिखेगा।

+0

मुझे परिणाम_एवर के रूप में क्या घोषित करना चाहिए? –

+1

उचित quote_FOO() फ़ंक्शन का उपयोग किये बिना गतिशील एसक्यूएल स्टेटमेंट में मूल्यों को कभी भी विभाजित न करें या आप इंजेक्शन हमलों के लिए दरवाजा खोलें। – dbenhur

+0

यह एक आंतरिक सामना डेटाबेस है। –

13

तालिका और स्तंभ नाम गतिशील कथन के रूप में निष्पादित करने के लिए गतिशील रूप से स्ट्रिंग का निर्माण किए बिना पैरामीटर या चर के रूप में निर्दिष्ट नहीं किए जा सकते हैं। पोस्टग्रेज़ में executing dynamic statements के बारे में उत्कृष्ट प्रारंभिक दस्तावेज है। quote_ident() या quote_literal() के साथ पहचानकर्ताओं और अक्षरों को उचित रूप से उद्धृत करना महत्वपूर्ण है। format() फ़ंक्शन गतिशील एसक्यूएल कथन निर्माण को साफ़ करने में मदद करता है। चूंकि आप SETOF INTEGER वापस करने के लिए फ़ंक्शन घोषित करते हैं, तो आपको * पर नहीं, पूर्णांक फ़ील्ड का चयन करना चाहिए।

CREATE OR REPLACE FUNCTION qa_scf(tname text, cname text) 
RETURNS SETOF INTEGER AS 
$BODY$ 
BEGIN 
    RETURN QUERY EXECUTE format(
    'SELECT the_integer_field FROM %I WHERE %I NOT IN (%L, %L)', 
            tname, cname, 'AK', 'CK' 
); 
END; 
$BODY$ 
LANGUAGE plpgsql; 
+0

मैं इसे सभी कॉलम कैसे वापस कर सकता हूं? –

+0

आप 'चयन * 'कर सकते हैं और' सेट्स सेट रिकॉर्ड 'घोषित कर सकते हैं। तब उपभोक्ता को रिकॉर्ड ट्यूपल समझना पड़ता है। http://wiki.postgresql.org/wiki/Return_more_than_one_row_of_data_from_PL/pgSQL_functions – dbenhur

+0

और मैं इसे कॉलम परिभाषा सूची कैसे दे सकता हूं? क्या गतिशील रूप से इसे खींचने का कोई तरीका है? –