简体   繁体   中英

Use substitution variable within Oracle IN clause

I'm trying to write a simple query where the requirement is to use a substitution variable that can be used to enter mutiple possible values for a column that's used for filtering the query.

The reqiurement is to produce the following query

select
CONTRACT, 
ORDER_NO,
CUSTOMER_NO
from CUSTOMER_ORDER
where state='Picked'
and contract in ('ABC','DEF')

but the contract values will need to be entered during runtime by means of a substitution variable. I'm working with the limitation of only being able to write a static SQL Query ("select..from..where..") and no dynamic code can be written inside pl sql blocks.

So, what I tried was the following,

select
CONTRACT, 
ORDER_NO,
CUSTOMER_NO
from CUSTOMER_ORDER_JOIN
where contract in (select '''' || REPLACE('&CONTRACT',';',''',''') || '''' from dual)

When the prompt appears for the substitution, I enter ABC;DEF

But this doesn't seem to work. Although when I run the following separately,

select '''' || REPLACE('&CONTRACT',';',''',''') || '''' from dual

I get 'ABC','DEF' as the result.

Why is this not working? Is there a way to achieve my desired result?

Thanks

One option is to split those values into rows and use them as a subquery.

Example based on Scott's EMP table:

SQL> select ename, job, sal from emp;

ENAME      JOB              SAL
---------- --------- ----------
SMITH      CLERK            920
ALLEN      SALESMAN        1600
WARD       SALESMAN        1250
JONES      MANAGER         2975
MARTIN     SALESMAN        1250
BLAKE      MANAGER         2850
CLARK      MANAGER         2450
SCOTT      ANALYST         3000
KING       PRESIDENT      10000
TURNER     SALESMAN        1500
ADAMS      CLERK           1100
JAMES      CLERK            950
FORD       ANALYST         3000
MILLER     CLERK           1300

14 rows selected.

SQL> select ename, job, sal
  2  from emp
  3  where ename in (select regexp_substr(replace(q'[&&par_ename]', chr(39), ''), '[^,]+', 1, level)
  4                  from dual
  5                  connect by level <= regexp_count(q'[&&par_ename]', ',') + 1
  6                 );
Enter value for par_ename: 'SMITH','ALLEN'

ENAME      JOB              SAL
---------- --------- ----------
SMITH      CLERK            920
ALLEN      SALESMAN        1600

SQL>

Alternatively, use sys.odcivarchar2list :

SQL> select ename, job, sal
  2  from emp
  3  where ename in (select column_value
  4                  from table(sys.odcivarchar2list(&par_ename))
  5                 );
Enter value for par_ename: 'SMITH','ALLEN'

ENAME      JOB              SAL
---------- --------- ----------
SMITH      CLERK            920
ALLEN      SALESMAN        1600

SQL>

It works without single quotes as well:

SQL> Select ename, job, sal
  2      from emp
  3      where ename in (select regexp_substr(replace(q'[&&par_ename]', chr(39), ''), '[^,]+', 1, level)
  4                      from dual
  5                      connect by level <= regexp_count(q'[&&par_ename]', ',') + 1
  6                     );
Enter value for par_ename: SMITH,ALLEN,KING

ENAME      JOB              SAL
---------- --------- ----------
SMITH      CLERK            920
ALLEN      SALESMAN        1600
KING       PRESIDENT      10000

SQL>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM