问题描述
DECLARE
l_filter varchar2(100);
BEGIN
SELECT filter INTO l_filter
FROM dashboard
WHERE id=TARGET_ID_1;
我从中得到l_filter为('016','018','011','014')。现在,我想在下面的查询中的IN子句中动态使用此l_filter值。
select a,b from grid
where filter_value in l_filter;
如何在PL / sql中执行此操作?
解决方法
您可以使用正则表达式:
select g.a,g.b
from grid g
where exists (select 1
from dashboard d.
where d.id = TARGET_ID_1 and
regexp_like(d.filter_value,'^(' || replace(d.filter,'''',''),','|') || ')$')
);
这不是特别有效,但是不需要任何PL / SQL或动态SQL。
也就是说,您可能希望将“过滤器”存储为表中的行,这样就可以将所有内容连接在一起,从而避免了复杂性。
,使用LIKE
:
DECLARE
l_filter varchar2(100);
cur SYS_REFCURSOR;
a GRID.A%TYPE;
b GRID.B%TYPE;
BEGIN
SELECT filter
INTO l_filter
FROM dashboard
WHERE id = TARGET_ID_1;
OPEN cur FOR
SELECT a,b
FROM grid
WHERE ','||SUBSTR(l_filter,2,LENGTH(l_filter)-2)||',' LIKE '%,'''||filter_value||''',%';
LOOP
FETCH cur INTO a,b;
EXIT WHEN cur%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(a || ',' || b);
END LOOP;
CLOSE cur;
END;
/
db 提琴here
,这就是我对这个问题的理解。
首先采样数据:
SQL> select * from dashboard;
ID FILTER
---------- -----------------------
1 '016','018','011','014'
2 '111','222'
SQL> select * from grid;
A B FIL
---------- ---------- ---
100 200 016
101 201 011
200 400 xxx
SQL>
返回refcursor的函数; 键(在此示例中)是将filter
值拆分为行,以便可以将它们用作子查询(第15-18行):
SQL> create or replace function f_get (target_id_1 in dashboard.id%type)
2 return sys_refcursor
3 is
4 l_filter varchar2(100);
5 rc sys_refcursor;
6 begin
7 select filter
8 into l_filter
9 from dashboard
10 where id = target_id_1;
11
12 open rc for
13 select g.a,g.b
14 from grid g
15 where g.filter_value in (select regexp_substr(replace(l_filter,chr(39),'[^,]+',1,level)
16 from dual
17 connect by level <= regexp_count(l_filter,') + 1
18 );
19
20 return rc;
21 end;
22 /
Function created.
测试:
SQL> select f_get(1) from dual;
F_GET(1)
--------------------
CURSOR STATEMENT : 1
CURSOR STATEMENT : 1
A B
---------- ----------
100 200
101 201
SQL>