2012-04-27 21 views
34

從值列表中選擇我指的這個stackoverflow答案:我如何在Oracle中

How can I select from list of values in SQL Server

怎麼能類似的東西在甲骨文做些什麼呢?

我已經看到在這個頁面上使用UNION的其他答案,雖然這種方法技術上的工作,這不是我想用在我的情況。

所以我想繼續使用或多或少看起來像逗號分隔的值列表的語法。

UPDATE關於create type tableanswer

我有一個表:

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

我使用這個腳本,但它不插入任何行至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 
; 

腳本輸出:

TYPE number_tab compiled 
Warning: execution completed with warning 

但如果我使用這個腳本它並插入新行到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 
; 

回答

47

您不需要創建任何存儲的類型,就可以評估Oracle的內置集合類型。

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

它的作品...!這正是我所尋找的。如果你可以找出爲什麼託尼安德魯斯的答案(http://stackoverflow.com/questions/10353969/how-can-i-select-from-list-of-values-in-oracle/10354083#10354083)給我一個警告,並沒有插入 - 請讓我知道。 – rapt 2012-04-30 12:37:36

+0

謝謝!在orcl 11g上爲我工作。我不禁想知道他們是如何拿出這些名字的? odcinumberlist vs dbms_debug_vc2coll這些似乎都沒有想到 – 2015-06-16 17:52:20

+1

@SonicSoul,因爲它們中沒有一個實際上意味着像我上面的答案中的「隨意」使用。 ODCI代表oracle數據盒式接口,dbms_debug_vc2_coll意味着與DBMS_DEBUG包一起使用。 – 2015-06-17 18:48:53

3

你可以這樣做:

create type number_tab is table of number; 

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

列由指定的名稱COLUMN_VALUE甲骨文,所以這個作品太:

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

它看起來像它應該工作管柱..但我得到:'TYPE number_tab編譯。警告:執行完成時會出現警告,並且在我使用此代碼的位置(在封裝「INSERT」中),封裝「INSERT」不起作用。例如。我做了INSERT INTO BOOK( BOOK_ID ) SELECT A.NOTEBOOK_ID FROM (select table_value AS NOTEBOOK_ID from table(number_tab(1,2,3,4,5,6)))A ;' - no row was插入...我做錯了什麼? – rapt 2012-04-27 16:40:48

+0

我不知道你在做什麼錯,或者是什麼錯:我也在11G上,它對我有用。你在創建類型時會發出什麼警告?我沒有收到任何警告。 – 2012-04-27 16:54:32

+0

請參閱上面的更新。 – rapt 2012-04-27 17:22:17

5

有多種方法可以採用逗號分隔列表並將其解析爲多行數據。在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. 

或者在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

根據我的經驗,我總是使用相同的問題邏輯。爲什麼你描述的方式來實現這個結果應該比使用集合更受歡迎?尤其是使用正則表達式和分層查詢的方法看起來非常複雜,無法評估!謝謝 – 2012-04-29 14:00:29

+0

@Justin Cave:謝謝,這真是太棒了! – rapt 2012-04-30 12:30:24

33

如果您正在尋求轉換逗號分隔值列表:

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

如果你想逗號的字符串轉換然後我會推薦Justin Cave的正則表達式SQL解決方案。

+0

不錯。我甚至不必授予該程序的權限! – Sebas 2015-09-11 22:09:09

0

嗨,還可以用於處理XML-表

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