2012-04-27 3 views
34

Ich beziehe mich auf diese stackoverflow Antwort:Wie kann ich wählen Sie aus der Liste von Werten in Oracle

How can I select from list of values in SQL Server

Wie konnte etwas ähnliches in Oracle getan werden?

Ich habe die anderen Antworten auf dieser Seite gesehen, die UNION verwenden und obwohl diese Methode technisch funktioniert, ist es nicht, was ich in meinem Fall verwenden möchte.

Also möchte ich bei der Syntax bleiben, die mehr oder weniger aussieht wie eine durch Kommas getrennte Liste von Werten.

UPDATEüber die create type tableanswer:

habe ich eine Tabelle:

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

ich dieses Skript verwenden, aber es einfügen keine Zeilen zur BOOK Tabelle:

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 
; 

Skriptausgabe:

TYPE number_tab compiled 
Warning: execution completed with warning 

Aber wenn ich dieses Skript verwenden wird es neue Zeilen in die BOOK Tabelle einfügen:

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

Antwort

47

Sie müssen keine gespeicherten Typen erstellen. Sie können die integrierten Sammlungstypen von Oracle auswerten.

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

Es funktioniert ...! und es ist, was ich gesucht habe. Wenn Sie herausfinden, warum Tony Andrews Antwort (http://stackoverflow.com/questions/10353969/how-can-i-select-from-list-of-values-in-oracle/10354083#10354083) gibt mir eine Warnung und produziert keine Einsätze - lassen Sie es mich wissen. – rapt

+0

danke! arbeitete für mich auf orcl 11g. Ich kann nicht anders, als mich zu fragen, wie sie auf diese Namen gekommen sind. odcinumberlist vs. dbms_debug_vc2coll nichts davon scheint überlegt zu sein –

+1

@SonicSoul weil keiner von ihnen eigentlich für "casual" Verwendung gedacht war wie in meiner Antwort oben. ODCI steht für Oracle Data Cartridge-Schnittstelle, dbms_debug_vc2_coll ist für die Verwendung mit dem DBMS_DEBUG-Paket vorgesehen. –

3

Sie dies tun können:

create type number_tab is table of number; 

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

Die Spalte den Namen spalten gegeben durch Oracle, so funktioniert das auch:

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

Es sieht aus wie es funktionieren sollte .. aber ich bin immer: 'TYPE number_tab zusammengestellt. Warnung: Ausführung mit Warnung abgeschlossen ", und wo ich diesen Code verwende (innerhalb einer Kapselung" INSERT "), funktioniert die Kapselung" INSERT "nicht. Z.B.Ich 'INSERT INTO BUCH ( BOOK_ID ) SELECT A.NOTEBOOK_ID VON (wählen spalten AS NOTEBOOK_ID aus der Tabelle (number_tab (1,2,3,4,5,6))) Ein ;' - keine Zeile war eingefügt ... was mache ich falsch? – rapt

+0

Ich weiß nicht, was du falsch machst oder was falsch ist: Ich bin auch auf 11G und es funktioniert von mir. Was ist die Warnung, die Sie beim Erstellen des Typs erhalten? Ich bekomme keine Warnung. –

+0

siehe Update oben. – rapt

5

Es gibt verschiedene Möglichkeiten, eine durch Kommas getrennte Liste in mehrere Datenzeilen zu zerlegen. 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. 

Oder 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. 
+0

Nach meiner Erfahrung habe ich immer die gleiche Logik der Frage verwendet. Warum sollten die Wege, die Sie beschrieben haben, um dieses Ergebnis zu erzielen, der Verwendung von Sammlungen vorgezogen werden? Vor allem die, die regexp und hierarchische Abfragen verwendet, sieht sehr komplex aus! Danke –

+0

@Justin Cave: Danke, es war brilliant! – rapt

33

Wenn Sie suchen eine kommagetrennte Liste von Werten zu konvertieren:

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

Wenn Sie eine Zeichenfolge von Komma umwandeln möchten Begrenzte Werte, dann würde ich Justin Cave's SQL-Lösung für reguläre Ausdrücke empfehlen.

+0

Schön. Ich musste diesem Verfahren nicht einmal Berechtigungen erteilen! – Sebas

0

Hallo es ist auch möglich, Strings mit XML-Tabelle

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