2012-04-27 35 views
34

tôi đề cập đến stackoverflow câu trả lời này:Làm thế nào tôi có thể chọn từ danh sách các giá trị trong Oracle

How can I select from list of values in SQL Server

Làm thế nào một cái gì đó tương tự có thể được thực hiện trong Oracle?

Tôi đã xem các câu trả lời khác trên trang này sử dụng UNION và mặc dù phương pháp này hoạt động về mặt kỹ thuật, nhưng đó không phải là những gì tôi muốn sử dụng trong trường hợp của mình.

Vì vậy, tôi muốn giữ nguyên cú pháp mà nhiều hoặc ít trông giống như danh sách giá trị được phân cách bằng dấu phẩy.

CẬP NHẬTvề create type tableanswer:

Tôi có một bảng:

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

tôi sử dụng kịch bản này nhưng nó không chèn thêm bất kỳ hàng vào BOOK bảng:

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 
; 

Kết quả tập lệnh:

TYPE number_tab compiled 
Warning: execution completed with warning 

Nhưng nếu tôi sử dụng kịch bản này nó chèn hàng mới đến BOOK bảng:

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

Trả lời

47

Bạn không cần phải tạo bất kỳ loại được lưu trữ nào, bạn có thể đánh giá các loại bộ sưu tập tích hợp của Oracle.

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

Nó hoạt động ...! và đó là những gì tôi đang tìm kiếm. Nếu bạn có thể tìm ra lý do tại sao câu trả lời của Tony Andrews (http://stackoverflow.com/questions/10353969/how-can-i-select-from-list-of-values-in-oracle/10354083#10354083) cho tôi một cảnh báo và không tạo ra sự chèn - xin vui lòng cho tôi biết. – rapt

+0

cảm ơn! làm việc cho tôi trên orcl 11g. tôi không thể không tự hỏi làm cách nào họ nghĩ ra những cái tên này? odcinumberlist vs dbms_debug_vc2coll không ai trong số này dường như nghĩ ra ở tất cả –

+1

@SonicSoul bởi vì không ai trong số họ thực sự có nghĩa là sử dụng "bình thường" như trong câu trả lời của tôi ở trên. ODCI là viết tắt của giao diện hộp mực dữ liệu oracle, dbms_debug_vc2_coll có nghĩa là được sử dụng với gói DBMS_DEBUG. –

3

Bạn có thể làm điều này:

create type number_tab is table of number; 

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

Cột được đưa ra tên COLUMN_VALUE bởi Oracle, do đó, điều này cũng hoạt động:

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

Có vẻ như nó nên làm việc .. nhưng tôi nhận được: 'LOẠI number_tab biên soạn. Cảnh báo: thực hiện hoàn thành với cảnh báo', và nơi tôi sử dụng mã này (bên trong một 'INSERT' đóng gói), việc đóng gói' INSERT' không hoạt động. Ví dụ.Tôi làm sách INSERT INTO ( BOOK_ID ) SELECT A.NOTEBOOK_ID TỪ (chọn cột_giá trị AS NOTEBOOK_ID từ bảng (number_tab (1,2,3,4,5,6))) ; '- không có hàng là chèn vào ... tôi đang làm gì sai? – rapt

+0

Tôi không biết những gì bạn đang làm sai, hoặc những gì là sai: Tôi đang trên 11G cũng và nó hoạt động từ tôi. Cảnh báo bạn đang nhận được khi tạo kiểu là gì? Tôi không nhận được bất kỳ cảnh báo nào. –

+0

vui lòng xem cập nhật ở trên. – rapt

5

Có nhiều cách khác nhau để lấy danh sách được phân tách bằng dấu phẩy và phân tích cú pháp thành nhiều hàng dữ liệu. Trong 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. 

Hoặc trong 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

Theo kinh nghiệm của tôi, tôi luôn sử dụng cùng một logic của câu hỏi. Tại sao các cách bạn mô tả để đạt được kết quả đó nên được ưu tiên sử dụng các bộ sưu tập? Đặc biệt là một trong đó sử dụng truy vấn regexp và phân cấp trông rất phức tạp để đánh giá! Cảm ơn –

+0

@Justin Cave: Cảm ơn bạn, nó thật tuyệt vời! – rapt

33

Nếu bạn đang tìm kiếm để chuyển đổi một dấu phẩy phân cách danh sách các giá trị:

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

Nếu bạn muốn chuyển đổi một chuỗi các dấu phẩy giá trị phân cách sau đó tôi muốn giới thiệu giải pháp SQL biểu thức chính quy của Justin Cave.

+0

Tốt. Tôi thậm chí không phải cấp quyền cho thủ tục đó! – Sebas

0

Hi nó cũng có thể cho Strings với XML-Table

SELECT trim(COLUMN_VALUE) str FROM xmltable(('"'||REPLACE('a1, b2, a2, c1', ',', '","')||'"')); 
Các vấn đề liên quan