PLSQL - 在 where 子句 IN 上使用变量数组
PLSQL - Use variable array on where clause IN
我希望在 WHERE IN 条件中使用一组值。
经过研究,我看到我必须制作一个“CREATE TYPE”,因为本地的“TYPE”不起作用。这个解决方案不适合我,我不想在 Oracle 中创建一个新的 TYPE,因为数据库用于 ERP/PGI 我不想用我的小需求污染。
我的要求如下:
DELETE vip_routage
WHERE vip_tel_ext = w_array_tel(i)
AND ((w_cp NOT IN ('14', '27', '50', '61', '76')
AND SUBSTR(VIP_CODE_POSTAL, 1, 2) IN ('14', '27', '50', '61', '76'))
OR (w_cp IN ('14', '27', '50', '61', '76')
AND SUBSTR(VIP_CODE_POSTAL, 1, 2) IN ('14', '27', '50', '61', '76')
AND TO_NUMBER(vip_dest1) < w_tri_ordre)
OR (w_cp NOT IN ('14', '27', '50', '61', '76')
AND SUBSTR(VIP_CODE_POSTAL, 1, 2) NOT IN ('14', '27', '50', '61', '76')
AND TO_NUMBER(vip_dest1) < w_tri_ordre));
这是我想设置为变量的值“('14','27','50','61','76')”,但仅限于我的程序。
除了“CREATE TYPE”你还有什么想法吗?
将第一个 with 子句和 str 替换为您的字符串变量,您可以这样做:
with rws as (
select '''14'',''27'',''50'',''61'',''76''' str from dual
),
item_list as (
select regexp_substr (
str,
'[^,]+',
1,
level
) value
from rws
connect by level <=
length ( str ) - length ( replace ( str, ',' ) ) + 1
)
delete from VIP_ROUTAGE
where vip_TEL_EXT = w_array_tel(i)
AND (
(w_cp NOT IN (select value from item_list)) ...
由于您不想创建自己的类型,请使用 built-in 一个 - sys.odcivarchar2list
。例如,获取是文员或经理的员工:
SQL> select deptno, empno, ename, job, sal
2 from emp
3 where job in (select *
4 from table(sys.odcivarchar2list('CLERK', 'MANAGER'))
5 );
DEPTNO EMPNO ENAME JOB SAL
---------- ---------- ---------- --------- ----------
10 7934 MILLER CLERK 1300
30 7900 JAMES CLERK 950
20 7876 ADAMS CLERK 1100
20 7369 SMITH CLERK 800
10 7782 CLARK MANAGER 2450
30 7698 BLAKE MANAGER 2850
20 7566 JONES MANAGER 2975
7 rows selected.
SQL>
如果您想声明一个数据类型为 sys.odcivarchar2list
的变量(因此,您在 PL/SQL 过程中),则
SQL> declare
2 l_job sys.odcivarchar2list := sys.odcivarchar2list('CLERK', 'MANAGER');
3 l_cnt number;
4 begin
5 select count(*)
6 into l_cnt
7 from emp
8 where job in (select * from table(l_job));
9
10 dbms_output.put_line('Found ' || l_cnt || ' employees');
11 end;
12 /
Found 7 employees
PL/SQL procedure successfully completed.
SQL>
可以传入一个字符串(如'14,27,50,61,76'
)作为绑定变量,使用LIKE
来比较分隔的字符串:
DELETE FROM VIP_ROUTAGE
WHERE vip_TEL_EXT = w_array_tel(i)
AND ( ',' || :your_list || ',' NOT LIKE '%,' || w_cp || ',%'
AND ( ',' || :your_list || ',' LIKE '%,' || SUBSTR(VIP_CODE_POSTAL,1,2) || '%,'
OR to_number(vip_dest1) < w_tri_ordre))
OR ( ',' || :your_list || ',' LIKE '%,' || w_cp || ',%'
AND ',' || :your_list || ',' LIKE '%,' || SUBSTR(VIP_CODE_POSTAL,1,2) || ',%'
AND to_number(vip_dest1) < w_tri_ordre)
db<>fiddle here
如果您希望将此代码列表作为纯文本(而不是作为集合类型的绑定变量)传递,则可以使用 json_table
函数将列表扩展为 table并将其用作一般 table 并在 in
谓词中使用子查询:
with function f
/*Just to emulate bind variable*/
return varchar2
as begin
return q'('X','Y','Z')';
end;
lkp as (
select *
from json_table(
'[' ||
/*
Your string goes here
instead of invocation f()
*/
f()
|| ']',
'$[*]'
columns (
col varchar2(100) path '$'
)
)
)
select *
from dual
where dummy in (
/*Filter by list*/
select * from lkp
)
| DUMMY |
| :---- |
| X |
db<>fiddle here
如果您想将此代码作为数组(Oracle 中的集合)传递,则使用 built-in 集合类型 sys.odcivarchar2list
,但您需要准备一个此类型的绑定变量应用程序端取决于编程语言(例如,here's an explanation 以及 Python 的官方文档中的示例)。
我希望在 WHERE IN 条件中使用一组值。
经过研究,我看到我必须制作一个“CREATE TYPE”,因为本地的“TYPE”不起作用。这个解决方案不适合我,我不想在 Oracle 中创建一个新的 TYPE,因为数据库用于 ERP/PGI 我不想用我的小需求污染。
我的要求如下:
DELETE vip_routage
WHERE vip_tel_ext = w_array_tel(i)
AND ((w_cp NOT IN ('14', '27', '50', '61', '76')
AND SUBSTR(VIP_CODE_POSTAL, 1, 2) IN ('14', '27', '50', '61', '76'))
OR (w_cp IN ('14', '27', '50', '61', '76')
AND SUBSTR(VIP_CODE_POSTAL, 1, 2) IN ('14', '27', '50', '61', '76')
AND TO_NUMBER(vip_dest1) < w_tri_ordre)
OR (w_cp NOT IN ('14', '27', '50', '61', '76')
AND SUBSTR(VIP_CODE_POSTAL, 1, 2) NOT IN ('14', '27', '50', '61', '76')
AND TO_NUMBER(vip_dest1) < w_tri_ordre));
这是我想设置为变量的值“('14','27','50','61','76')”,但仅限于我的程序。
除了“CREATE TYPE”你还有什么想法吗?
将第一个 with 子句和 str 替换为您的字符串变量,您可以这样做:
with rws as (
select '''14'',''27'',''50'',''61'',''76''' str from dual
),
item_list as (
select regexp_substr (
str,
'[^,]+',
1,
level
) value
from rws
connect by level <=
length ( str ) - length ( replace ( str, ',' ) ) + 1
)
delete from VIP_ROUTAGE
where vip_TEL_EXT = w_array_tel(i)
AND (
(w_cp NOT IN (select value from item_list)) ...
由于您不想创建自己的类型,请使用 built-in 一个 - sys.odcivarchar2list
。例如,获取是文员或经理的员工:
SQL> select deptno, empno, ename, job, sal
2 from emp
3 where job in (select *
4 from table(sys.odcivarchar2list('CLERK', 'MANAGER'))
5 );
DEPTNO EMPNO ENAME JOB SAL
---------- ---------- ---------- --------- ----------
10 7934 MILLER CLERK 1300
30 7900 JAMES CLERK 950
20 7876 ADAMS CLERK 1100
20 7369 SMITH CLERK 800
10 7782 CLARK MANAGER 2450
30 7698 BLAKE MANAGER 2850
20 7566 JONES MANAGER 2975
7 rows selected.
SQL>
如果您想声明一个数据类型为 sys.odcivarchar2list
的变量(因此,您在 PL/SQL 过程中),则
SQL> declare
2 l_job sys.odcivarchar2list := sys.odcivarchar2list('CLERK', 'MANAGER');
3 l_cnt number;
4 begin
5 select count(*)
6 into l_cnt
7 from emp
8 where job in (select * from table(l_job));
9
10 dbms_output.put_line('Found ' || l_cnt || ' employees');
11 end;
12 /
Found 7 employees
PL/SQL procedure successfully completed.
SQL>
可以传入一个字符串(如'14,27,50,61,76'
)作为绑定变量,使用LIKE
来比较分隔的字符串:
DELETE FROM VIP_ROUTAGE
WHERE vip_TEL_EXT = w_array_tel(i)
AND ( ',' || :your_list || ',' NOT LIKE '%,' || w_cp || ',%'
AND ( ',' || :your_list || ',' LIKE '%,' || SUBSTR(VIP_CODE_POSTAL,1,2) || '%,'
OR to_number(vip_dest1) < w_tri_ordre))
OR ( ',' || :your_list || ',' LIKE '%,' || w_cp || ',%'
AND ',' || :your_list || ',' LIKE '%,' || SUBSTR(VIP_CODE_POSTAL,1,2) || ',%'
AND to_number(vip_dest1) < w_tri_ordre)
db<>fiddle here
如果您希望将此代码列表作为纯文本(而不是作为集合类型的绑定变量)传递,则可以使用 json_table
函数将列表扩展为 table并将其用作一般 table 并在 in
谓词中使用子查询:
with function f /*Just to emulate bind variable*/ return varchar2 as begin return q'('X','Y','Z')'; end; lkp as ( select * from json_table( '[' || /* Your string goes here instead of invocation f() */ f() || ']', '$[*]' columns ( col varchar2(100) path '$' ) ) ) select * from dual where dummy in ( /*Filter by list*/ select * from lkp )
| DUMMY | | :---- | | X |
db<>fiddle here
如果您想将此代码作为数组(Oracle 中的集合)传递,则使用 built-in 集合类型 sys.odcivarchar2list
,但您需要准备一个此类型的绑定变量应用程序端取决于编程语言(例如,here's an explanation 以及 Python 的官方文档中的示例)。