Oracle
 sql >> डेटाबेस >  >> RDS >> Oracle

मैं डायनामिक WHERE क्लॉज कैसे बना सकता हूं?

ऑब्जेक्ट गतिशील रूप से 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> 

यह तालिका एक फ़ंक्शन को पास की जाती है, जो सरणी के चारों ओर लूप करती है। सरणी में प्रत्येक प्रविष्टि के लिए यह ='' प्रारूप में WHERE क्लॉज में एक पंक्ति जोड़ता है। संभवतः आपको अधिक परिष्कृत फ़िल्टरिंग की आवश्यकता होगी - विभिन्न ऑपरेटर, स्पष्ट डेटा प्रकार रूपांतरण, बाइंड चर - लेकिन यह सामान्य विचार है।

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>


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. एक कस्टम कॉलम नाम के साथ एक विदेशी कुंजी मैप करना

  2. Oracle में UTF8 वर्ण सेट को कैसे कॉन्फ़िगर करें?

  3. मैं डायनेमिक SQL में DDL/SCL स्टेटमेंट में बाइंड वेरिएबल्स का उपयोग क्यों नहीं कर सकता?

  4. पीएल/एसक्यूएल में स्ट्रिंग को कैसे विभाजित करें?

  5. Oracle डेटाबेस बैकअप:बैकअप और बैकअप रणनीति का प्रकार