Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

Làm cách nào để tạo mệnh đề WHERE động?

Đối tượng là để tập hợp động một câu lệnh từ một số bộ lọc thay đổi trong mệnh đề WHERE. Tôi không chắc nơi đệ quy phù hợp với tất cả những điều này, vì vậy tôi sẽ chỉ sử dụng một mảng để xử lý các tham số:

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> 

Bảng này được chuyển cho một hàm, hàm này lặp lại xung quanh mảng. Đối với mỗi mục nhập trong mảng, nó thêm một dòng vào mệnh đề WHERE ở định dạng =''. Có thể bạn sẽ yêu cầu lọc phức tạp hơn - các toán tử khác nhau, chuyển đổi kiểu dữ liệu rõ ràng, biến ràng buộc - nhưng đây là ý tưởng chung.

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> 

Cuối cùng để thực hiện truy vấn này, chúng ta cần điền một biến cục bộ của kiểu mảng và trả kết quả về một con trỏ tham chiếu.

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>    

chỉnh sửa

Trong đoạn cuối cùng của câu hỏi, OP nói rằng họ đang sử dụng XML để vượt qua các tiêu chí. Yêu cầu này không thay đổi đáng kể hình dạng của triển khai ban đầu của tôi. Vòng lặp chỉ cần loại bỏ truy vấn XPath thay vì một mảng:

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>

Có thể thấy, phiên bản này trả về kết quả tương tự như trước ...

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. Thu thập thống kê giản đồ bằng FND_STATS trong EBS 11i và R12

  2. Hàm JSON_ARRAY () trong Oracle

  3. Cách tạo báo cáo PDF bằng PL / SQL

  4. 7 điều cần biết về các ngăn trên Cơ sở hạ tầng đám mây Oracle

  5. Oracle - Tại sao tôi nên sử dụng các gói thay vì các thủ tục hoặc hàm độc lập