#sql #oracle
#sql #Oracle
Вопрос:
Я пытаюсь написать простой запрос, в котором требуется использовать переменную подстановки, которая может использоваться для ввода нескольких возможных значений для столбца, используемого для фильтрации запроса.
Требование заключается в создании следующего запроса
select
CONTRACT,
ORDER_NO,
CUSTOMER_NO
from CUSTOMER_ORDER
where state='Picked'
and contract in ('ABC','DEF')
но значения контракта необходимо будет вводить во время выполнения с помощью переменной подстановки. Я работаю с ограничением возможности записи только статического SQL-запроса («select ..from ..where ..»), и никакой динамический код не может быть записан внутри блоков pl sql.
Итак, то, что я попробовал, было следующим,
select
CONTRACT,
ORDER_NO,
CUSTOMER_NO
from CUSTOMER_ORDER_JOIN
where contract in (select '''' || REPLACE('amp;CONTRACT',';',''',''') || '''' from dual)
Когда появляется запрос на подстановку, я ввожу ABC;DEF
Но, похоже, это не работает. Хотя, когда я запускаю следующее отдельно,
select '''' || REPLACE('amp;CONTRACT',';',''',''') || '''' from dual
В результате я получаю ‘ABC’, ‘DEF’.
Почему это не работает? Есть ли способ достичь желаемого результата?
Спасибо
Ответ №1:
Один из вариантов — разделить эти значения на строки и использовать их в качестве подзапроса.
Пример, основанный на таблице EMP Скотта:
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'[amp;amp;par_ename]', chr(39), ''), '[^,] ', 1, level)
4 from dual
5 connect by level <= regexp_count(q'[amp;amp;par_ename]', ',') 1
6 );
Enter value for par_ename: 'SMITH','ALLEN'
ENAME JOB SAL
---------- --------- ----------
SMITH CLERK 920
ALLEN SALESMAN 1600
SQL>
В качестве альтернативы используйте sys.odcivarchar2list
:
SQL> select ename, job, sal
2 from emp
3 where ename in (select column_value
4 from table(sys.odcivarchar2list(amp;par_ename))
5 );
Enter value for par_ename: 'SMITH','ALLEN'
ENAME JOB SAL
---------- --------- ----------
SMITH CLERK 920
ALLEN SALESMAN 1600
SQL>
Он также работает без одинарных кавычек:
SQL> Select ename, job, sal
2 from emp
3 where ename in (select regexp_substr(replace(q'[amp;amp;par_ename]', chr(39), ''), '[^,] ', 1, level)
4 from dual
5 connect by level <= regexp_count(q'[amp;amp;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>
Комментарии:
1. Спасибо. Но я не хочу, чтобы входные данные были в одинарных кавычках, таких как ‘SMITH’, ‘ALLEN’. Скорее я собираюсь ввести SMITH; ALLEN. Можно ли этого достичь?
2. Пожалуйста, и вы могли бы попробовать это сами. Это работает и без одинарных кавычек; взгляните на отредактированный ответ.
3. Потрясающе! На самом деле это так.. Это было очень полезно! Еще раз спасибо