2011-01-12 9 views
7

Mam ciąg rozdzielany przecinkami, który chcę użyć w klauzuli "IN" instrukcji. np: 100.101.102Korzystanie z klauzuli "IN" ze znakiem rozdzielanym przecinkami z wyjścia funkcji replace() w Oracle SQL

ponieważ w i "IN" klauzuli muszę zacytować individial sznurki, używam funkcji Replace: np: wybierz '' '' || zastąpić ('100101102', '',” '', '' ') ||' '' 'od dual;

Powyższe zapytanie działa jednak, gdy próbuję użyć wyniku powyższego jako wejścia do klauzuli "IN", to nie zwraca żadnych danych. Ograniczają mnie tylko instrukcje SQL, więc nie mogę używać kodu PL/SQL. Uprzejma pomoc.

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

Powyższe nie działa. Daj mi znać, czego mi brakuje.

+0

to liczba identyfikatorów na liście ograniczone? –

Odpowiedz

9

Ogólnym podejściem w tym przypadku byłoby przeanalizowanie rozdzielonej przecinkami listy w zbiorze Oracle i użycie tej kolekcji w instrukcji SQL. Tom Kyte ma tego przykład w swojej dyskusji na temat variable IN lists.

Zakładając utworzyć rodzaj myTableType i funkcję in_list z tego wątku, powinieneś być w stanie zrobić

SELECT * 
    FROM employee 
WHERE employee_number IN (
    SELECT * 
     FROM TABLE(in_list(p_your_comma_separated_list)) 
    ) 
+0

Witaj Justin, dzięki za sugestię. Niestety nie mam dostępu do bazy danych, aby zmienić lub stworzyć cokolwiek. Mam dostęp tylko do odczytu, dlatego jestem ograniczony tylko do "wybierania". – Thomas

4

czystego SQL, ale nie bardzo dobrze przetestowane ...

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; 

EDYCJA: poprawiona

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 
); 

Uwaga:

  • pre/post naprawić swoje struny z przecinkiem
  • przyjąć górną granicę (10 w tym przykładzie) jak na swoje potrzeby (nie są potrzebne w ulepszonej wersji).
  • użyć funkcji tabeli in_list wspomniany przez Justing Cave, że chyba lepiej :)

kredytowej: coś, co jest w książce Stephane Faroult za "Aplikacje Refactorying SQL" (O'Reilly)

+0

Witaj Markusie, dziękuję. Rozwiązanie dostarczone przez ciebie przy użyciu czystego sql działa doskonale. Dzięki tobie i Justinowi za twoją pomoc. – Thomas

2

Jak wartości oddzielone przecinkami zawierać tylko cyfry, to dlaczego nie spróbować czegoś tak prostego jak zastosowanie:

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

Zobacz ten przykład:

-- 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 

Produkcja:

EMPLOYEE_NUMBER 
101 
102 
0

można używać podejście zastąpić i, jeśli sformatować cały wybierz jako ciąg - następnie użyć ciąg albo OPEN refcursor FOR lub EXECUTE natychmiastowe.

-1

Możesz użyć funkcji regexp_substr, aby uzyskać oczekiwany wynik.
Na przykład NAZWY: = 'SMITH, ALLEN, WARD, JONES'; - tutaj "NAZWISKO" jest zmienną/wynikiem oczekiwanego wejścia. Może być użyta w KWESTII ZEWNĘTRZNEJ.

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 

Powyższe iteracji zapytania poprzez oddzielony przecinkami łańcucha, wyszukuje przecinek (,), a następnie dzieli się przez traktowanie ciąg przecinek separatora. Zwraca łańcuch jako wiersz, gdy trafi separator.
Oto referencyjny Click Here

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 
+1

Podczas gdy ten link może odpowiedzieć na pytanie, lepiej umieścić tutaj istotne części odpowiedzi i podać link do odsyłacza. Odpowiedzi dotyczące linków mogą stać się nieprawidłowe, jeśli strona z linkami się zmieni. - [Z recenzji] (/ opinia/niskiej jakości-posts/18420868) –

Powiązane problemy