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

Oracle:Truy vấn được tham số hóa với mệnh đề IN trả về giá trị null

Bạn có thể chuyển danh sách được phân tách bằng dấu phẩy dưới dạng tham số (biến liên kết), nhưng bạn chịu trách nhiệm phân tích cú pháp nó trong một truy vấn con. Giải pháp dựa trên chuỗi này sử dụng regexp_substr.

CREATE or REPLACE PROCEDURE p_getdata(A IN VARCHaR2, cur OUT sys_refcursor)
AS
BEGIN
open cur for  'with t1 as (select :A col from dual),
     t2 as (select level lvl,to_number(regexp_substr(col,''[^,]+'', 1, level)) col 
              from t1 connect by regexp_substr(col, ''[^,]+'', 1, level) is not null)
select col as id from t2' using A;
END;
/

Thủ tục được đơn giản hóa, nhưng phải cung cấp cảm giác về cách sử dụng nó.

Ưu điểm lớn chống lại việc sử dụng SQL động (nối các chuỗi) là bạn không cần phải phân tích cú pháp câu lệnh trên mỗi lần thực thi. Chưa kể đến vấn đề bảo mật (sự sợ hãi của SQL injection).

Cách sử dụng:

DECLARE 
  l_cur SYS_REFCURSOR;
  l_id NUMBER;
BEGIN 
  p_getdata('1,1000,282828,4',l_cur);
 LOOP
    FETCH l_cur INTO l_id ;
    EXIT WHEN l_cur%NOTFOUND;
    dbms_output.put_line(l_id);
 END LOOP;
END;
/


1
1000
282828
4

CẬP NHẬT

Quy trình trên được đơn giản hóa, để có được chức năng của bạn, bạn nên sử dụng một truy vấn như thế này trong CURSOR (tức là trước tiên hãy tách tất cả ba tham số trong các truy vấn con riêng biệt bằng cách sử dụng tính năng truy vấn con, thay vì áp dụng kết quả trong truy vấn của bạn)

CREATE or REPLACE PROCEDURE p_getdata(A IN VARCHAR2, B in VARCHAR2, c in VARCHAR2, cur OUT sys_refcursor)
AS
BEGIN
open cur for  'with ta1 as (select :A col from dual),
     ta2 as (select level lvl,to_number(regexp_substr(col,''[^,]+'', 1, level)) col 
              from ta1 connect by regexp_substr(col, ''[^,]+'', 1, level) is not null),
 tb1 as (select :B col from dual),
     tb2 as (select level lvl,to_number(regexp_substr(col,''[^,]+'', 1, level)) col 
              from tb1 connect by regexp_substr(col, ''[^,]+'', 1, level) is not null),
 tc1 as (select :C col from dual),
     tc2 as (select level lvl,to_number(regexp_substr(col,''[^,]+'', 1, level)) col 
              from tc1 connect by regexp_substr(col, ''[^,]+'', 1, level) is not null)              
select firstname, lastname, streetname, city
from mytable 
where zip IN (select col from ta2) AND 
      streetnumber IN (select col from tb2) AND 
      apt_num in (select col from tc2)' using A, B, C;
END;
/

bài kiểm tra đã vượt qua

DECLARE 
  l_cur SYS_REFCURSOR;
  l_firstname VARCHAR2(20);
  l_lastname VARCHAR2(20);
  l_streetname VARCHAR2(20);
  l_city VARCHAR2(20);
BEGIN 
  p_getdata('1100,,1200','1,2','11,12' ,l_cur);
 LOOP
    FETCH l_cur INTO l_firstname, l_lastname, l_streetname, l_city;
    EXIT WHEN l_cur%NOTFOUND;
    dbms_output.put_line(l_firstname|| ' ' || l_lastname || ' ' || l_streetname  || ' ' || l_city);
 END LOOP;
END;
/


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Thứ tự MySQL theo kết quả phù hợp nhất

  2. Sự cố với chuỗi kết nối trong tệp cấu hình web

  3. Không thể kết nối với MySQL trong Cloudbees CommunicationsException:Lỗi liên kết truyền thông

  4. Cách ghép nhiều giá trị nối từ nhiều bảng quan hệ trong một truy vấn mysql duy nhất

  5. Đặt các biến Truy vấn lớn như mysql