Come posso selezionare dalla lista di valori in Oracle

Mi riferisco a questa risposta stackoverflow :

Come posso selezionare dall’elenco di valori in SQL Server

Come potrebbe essere fatto qualcosa di simile in Oracle ?

Ho visto le altre risposte su questa pagina che usano UNION e sebbene questo metodo funzioni tecnicamente, non è quello che vorrei usare nel mio caso.

Quindi vorrei rimanere con la syntax che più o meno assomiglia ad un elenco di valori separati da virgole.

AGGIORNAMENTO relativo alla risposta della create type table :

Ho un tavolo:

 CREATE TABLE "BOOK" ( "BOOK_ID" NUMBER(38,0) ) 

Io uso questo script ma non inserisce alcuna riga nella tabella BOOK :

 create type number_tab is table of number; INSERT INTO BOOK ( BOOK_ID ) SELECT A.NOTEBOOK_ID FROM (select column_value AS NOTEBOOK_ID from table (number_tab(1,2,3,4,5,6))) A ; 

Script di output:

 TYPE number_tab compiled Warning: execution completed with warning 

Ma se uso questo script, inserisce nuove righe nella tabella BOOK :

 INSERT INTO BOOK ( BOOK_ID ) SELECT A.NOTEBOOK_ID FROM (SELECT (LEVEL-1)+1 AS NOTEBOOK_ID FROM DUAL CONNECT BY LEVEL<=6) A ; 

Non è necessario creare alcun tipo memorizzato, è ansible valutare i tipi di raccolta incorporati di Oracle.

 select distinct column_value from table(sys.odcinumberlist(1,1,2,3,3,4,4,5)) 

Se stai cercando di convertire un elenco di valori delimitati da virgole:

 select column_value from table(sys.dbms_debug_vc2coll('One', 'Two', 'Three', 'Four')); -- Or select column_value from table(sys.dbms_debug_vc2coll(1,2,3,4)); 

Se si desidera convertire una stringa di valori delimitati da virgole, raccomanderei la soluzione SQL per le espressioni regolari di Justin Cave.

Esistono vari modi per prendere un elenco separato da virgole e analizzarlo in più righe di dati. In SQL

 SQL> ed Wrote file afiedt.buf 1 with x as ( 2 select '1,2,3,a,b,c,d' str from dual 3 ) 4 select regexp_substr(str,'[^,]+',1,level) element 5 from x 6* connect by level <= length(regexp_replace(str,'[^,]+')) + 1 SQL> / ELEMENT ---------------------------------------------------- 1 2 3 a b c d 7 rows selected. 

O in PL / SQL

 SQL> create type str_tbl is table of varchar2(100); 2 / Type created. SQL> create or replace function parse_list( p_list in varchar2 ) 2 return str_tbl 3 pipelined 4 is 5 begin 6 for x in (select regexp_substr( p_list, '[^,]', 1, level ) element 7 from dual 8 connect by level <= length( regexp_replace( p_list, '[^,]+')) + 1) 9 loop 10 pipe row( x.element ); 11 end loop 12 return; 13 end; 14 15 / Function created. SQL> select * 2 from table( parse_list( 'a,b,c,1,2,3,d,e,foo' )); COLUMN_VALUE -------------------------------------------------------------------------------- a b c 1 2 3 d e f 9 rows selected. 

Puoi farlo:

 create type number_tab is table of number; select * from table (number_tab(1,2,3,4,5,6)); 

La colonna ha il nome COLUMN_VALUE di Oracle, quindi anche questo funziona:

 select column_value from table (number_tab(1,2,3,4,5,6)); 

Ciao è anche ansible per le stringhe con XML-Table

 SELECT trim(COLUMN_VALUE) str FROM xmltable(('"'||REPLACE('a1, b2, a2, c1', ',', '","')||'"')); 

A partire da Oracle 12.2, non è necessaria la funzione TABLE , è ansible selezionare direttamente dalla raccolta integrata.

 SQL> select * FROM sys.odcinumberlist(5,2,6,3,78); COLUMN_VALUE ------------ 5 2 6 3 78 SQL> select * FROM sys.odcivarchar2list('A','B','C','D'); COLUMN_VALUE ------------ A B C D