Использование предложения «IN» со строкой, разделенной запятыми, из вывода функции replace () в Oracle SQL - PullRequest
8 голосов
/ 12 января 2011

У меня есть строка с разделителями-запятыми, которую я хочу использовать в предложении IN. например: 100 101,102

Поскольку в In и предложении IN нужно заключать в кавычки отдельные строки, я использую функцию replace: Например: выберите '' '' || replace ('100,101,102', ',', '' ',' '') || '' '' из двойного;

Вышеупомянутый запрос работает, однако, когда я пытаюсь использовать вывод вышеупомянутого в качестве входных данных для предложения "IN", он не возвращает данных. Я ограничен только инструкциями SQL, поэтому я не могу использовать код PL / SQL. Пожалуйста, помогите.

select * from employee where employee_number in (
    select ''''||replace('100,101,102',',',''', ''')||'''' from dual);

Выше не работает. Пожалуйста, дайте мне знать, что мне не хватает.

Ответы [ 5 ]

11 голосов
/ 12 января 2011

Общий подход в этом случае состоит в том, чтобы разобрать список через запятую в коллекцию Oracle и использовать эту коллекцию в вашем операторе SQL. Пример этого есть у Тома Кайта в обсуждении переменных IN списков .

Предполагая, что вы создадите тип myTableType и функцию in_list из этого потока, вы сможете выполнить

SELECT *
  FROM employee
 WHERE employee_number IN (
    SELECT *
      FROM TABLE( in_list( p_your_comma_separated_list ) )
    )
4 голосов
/ 12 января 2011

чистый SQL, но не очень хорошо проверенный ...

select to_number(substr(postfix, 2, instr(postfix, ',' ,2)-2)) id 
  from (
       select substr(val, instr(val, ',', 1, n)) postfix 
         from (select ',101,102,103,' val from dual)
     , (
       select level n
         from dual 
      connect by level < 10) 
  where instr(val, ',', 1, n) > 0)
 where  instr(postfix, ',' ,2)> 2;

РЕДАКТИРОВАТЬ : улучшено

select substr(postfix, 1, instr(postfix, ',' ,1)-1)
  from (
       select substr(val, instr(val, ',',1, level)+1) postfix
         from (select ',101,102,103,' val from dual)
      connect by instr(val, ',', 2, level) > 0
  );

Примечание:

  • до / после исправления строк с запятой
  • принять верхний предел (10 в примере) в соответствии с вашими потребностями (не требуется в улучшенной версии).
  • используйте табличную функцию in_list, упомянутую Justing Cave, это, вероятно, лучше:)

credit: нечто подобное есть в книге Стефана Фарула «Рефакторинг приложений SQL» (O'Reilly)

2 голосов
/ 27 сентября 2014

Поскольку значения, разделенные запятыми, содержат только цифры, почему бы не попробовать что-нибудь простое, например:

INSTR(','||my_csv_list_of_values||',', ','||my_search_value||',') <> 0

См. Этот пример:

-- some test data
with employee as (
  select 101 as employee_number from dual
  union select 200 from dual
  union select 10 from dual
  union select 102 from dual)

-- the actual query
select * from employee
  where INSTR(','||'101,102,103,104'||',', ','||employee_number||',') <> 0;
--                 ^^^^^^^^^^^^^^^^^
--                   your CSV data

Производство:

EMPLOYEE_NUMBER
101
102
0 голосов
/ 04 января 2018

Вы можете использовать функцию regexp_substr , чтобы получить ожидаемый результат.
Например ИМЕНА: = 'SMITH, ALLEN, WARD, JONES'; - здесь «Имена» - это переменная / результат ожидаемого ввода. Его можно использовать в предложении IN.

SQL> select regexp_substr(NAMES,'[^,]+', 1, level) from dual 2  connect by regexp_substr(NAMES, '[^,]+', 1, level) is not null;


REGEXP_SUBSTR('SMITH,A
----------------------
SMITH
ALLEN
WARD
JONES

Приведенный выше запрос повторяет строку, разделенную запятыми, ищет запятую (,) и затем разбивает строку, обрабатывая запятую как разделитель. Он возвращает строку в виде строки всякий раз, когда попадает в разделитель.
Вот ссылка Нажмите здесь

 SQL> select * from emp where ename in (
  2  select regexp_substr('SMITH,ALLEN,WARD,JONES','[^,]+', 1, level) from dual
  3  connect by regexp_substr('SMITH,ALLEN,WARD,JONES', '[^,]+', 1, level) is not null );



     EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 17-DEC-80        800                    20
      7499 ALLEN      SALESMAN        7698 20-FEB-81       1600        300         30
      7521 WARD       SALESMAN        7698 22-FEB-81       1250        500         30
      7566 JONES      MANAGER         7839 02-APR-81       2975                    20
0 голосов
/ 27 сентября 2014

Вы можете использовать свой подход с REPLACE и IN, если вы отформатируете весь select как строку - затем используйте строку с OPEN refcursor FOR или EXECUTE IMMEDIATE.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...