ऑब्जेक्ट गतिशील रूप से WHERE क्लॉज में फ़िल्टर की एक चर संख्या से एक स्टेटमेंट को इकट्ठा करना है। मुझे यकीन नहीं है कि रिकर्सन कहां फिट बैठता है, इसलिए मैं पैरामीटर को संभालने के लिए केवल एक सरणी का उपयोग करूंगा:
SQL> create type qry_param as object
2 (col_name varchar2(30)
3 , col_value varchar(20))
4 /
Type created.
SQL> create type qry_params as table of qry_param
2 /
Type created.
SQL>
यह तालिका एक फ़ंक्शन को पास की जाती है, जो सरणी के चारों ओर लूप करती है। सरणी में प्रत्येक प्रविष्टि के लिए यह
SQL> create or replace function get_emps
2 (p_args in qry_params )
3 return sys_refcursor
4 as
5 stmt varchar2(32767);
6 rc sys_refcursor;
7 begin
8 stmt := ' select * from emp';
9 for i in p_args.first()..p_args.last()
10 loop
11 if i = 1 then
12 stmt := stmt || ' where ';
13 else
14 stmt := stmt || ' and ';
15 end if;
16 stmt := stmt || p_args(i).col_name
17 ||' = '''||p_args(i).col_value||'''';
18 end loop;
19 open rc for stmt;
20 return rc;
21 end get_emps;
22 /
Function created.
SQL>
अंत में इस क्वेरी को निष्पादित करने के लिए हमें सरणी प्रकार के स्थानीय चर को पॉप्युलेट करना होगा और परिणाम को रेफ कर्सर पर वापस करना होगा।
SQL> var l_rc refcursor
SQL> declare
2 l_args qry_params := qry_params
3 (qry_param('DEPTNO', '50')
4 , qry_param('HIREDATE', '23-MAR-2010'));
5 begin
6 :l_rc := get_emps(l_args);
7 end;
8 /
PL/SQL procedure successfully completed.
SQL> print l_rc
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
8041 FEUERSTEIN PLUMBER 7839 23-MAR-10 4250 50
8040 VERREYNNE PLUMBER 7839 23-MAR-10 4500 50
SQL>
संपादित करें
अपने प्रश्न के अंतिम पैराग्राफ में ओपी का कहना है कि वे मानदंड पारित करने के लिए एक्सएमएल का उपयोग कर रहे हैं। यह आवश्यकता नाटकीय रूप से मेरे मूल कार्यान्वयन के आकार को नहीं बदलती है। लूप को केवल एक सरणी के बजाय एक XPath क्वेरी को बंद करने की आवश्यकता होती है:
SQL> create or replace function get_emps
2 (p_args in xmltype )
3 return sys_refcursor
4 as
5 stmt varchar2(32767);
6 rc sys_refcursor;
7 begin
8 stmt := ' select * from emp';
9 for i in (select * from xmltable (
10 '/params/param'
11 passing p_args
12 columns
13 position for ordinality
14 , col_name varchar2(30) path '/param/col_name'
15 , col_value varchar2(30) path '/param/col_value'
16 )
17 )
18 loop
19 if i.position = 1 then
20 stmt := stmt || ' where ';
21 else
22 stmt := stmt || ' and ';
23 end if;
24 stmt := stmt || i.col_name
25 ||' = '''||i.col_value||'''';
26 end loop;
27 open rc for stmt;
28 return rc;
29 end get_emps;
30 /
Function created.
SQL>
जैसा कि देखा जा सकता है, यह संस्करण पहले जैसा ही परिणाम देता है...
SQL> var l_rc refcursor
SQL> declare
2 l_args xmltype := xmltype
3 ('<params>
4 <param>
5 <col_name>DEPTNO</col_name>
6 <col_value>50</col_value>
7 </param>
8 <param>
9 <col_name>HIREDATE</col_name>
10 <col_value>23-MAR-2010</col_value>
11 </param>
12 </params>');
13 begin
14 :l_rc := get_emps(l_args);
15 end;
16 /
PL/SQL procedure successfully completed.
SQL> print l_rc
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
8041 FEUERSTEIN PLUMBER 7839 23-MAR-10 4250 50
8040 VERREYNNE PLUMBER 7839 23-MAR-10 4500 50
SQL>