2013-04-24 40 views
5

Tôi đang sử dụng bộ sưu tập trong khối mã oracle vì không có biến bảng (như trong MS SQL Server).Bộ sưu tập Oracle trong mệnh đề

DECLARE 
    TYPE I_NAME IS TABLE OF NVARCHAR2(512);  
    I_ITEMNAME  I_NAME := I_NAME(); 
BEGIN 

Tôi đang sử dụng "BULK COLLECT INTO I_ITEMNAME" để điền vào bộ sưu tập.
Tôi muốn sử dụng bộ sưu tập này trong mệnh đề WHERE trong truy vấn SELECT nhưng không thể tìm thấy phương pháp để làm điều đó. Hiện tại tôi và sử dụng vòng lặp FOR và nhận từng mục một.
Làm cách nào để tôi có thể sử dụng bộ sưu tập trực tiếp trong mệnh đề WHERE somethin như

SELECT * FROM TBL WHERE COL IN I_ITEMNAME?

Cảm ơn bạn,

Trả lời

9

Bạn không thể sử dụng một bộ sưu tập bố cục bộ trong một khoản SQL:

declare 
    type i_name is table of nvarchar2(512); 
    i_itemname i_name := i_name(); 
    c number; 
begin 
    select distinct owner bulk collect into i_itemname from all_objects; 
    dbms_output.put_line(i_itemname.count); 
    select count(*) into c 
    from all_tables 
    where owner in (select * from table(i_itemname)); 
    dbms_output.put_line(c); 
end; 
/

    where owner in (select * from table(i_itemname)); 
             * 
ERROR at line 10: 
ORA-06550: line 10, column 41: 
PLS-00642: local collection types not allowed in SQL statements 
ORA-06550: line 10, column 35: 
PL/SQL: ORA-22905: cannot access rows from a non-nested table item 
ORA-06550: line 8, column 5: 
PL/SQL: SQL Statement ignored 

Nhưng bạn có thể nếu nó tuyên bố ở mức lược đồ, chủ yếu để SQL biết về loại này, không chỉ PL/SQL:

create type i_name is table of nvarchar2(512); 
/

Type created. 

declare 
    i_itemname i_name := i_name();  
    c number; 
begin 
    select distinct owner bulk collect into i_itemname from all_objects; 
    dbms_output.put_line(i_itemname.count); 
    select count(*) into c from all_tables 
    where owner in (select * from table(i_itemname)); 
    dbms_output.put_line(c); 
end; 
/

No errors. 
18 
128 

PL/SQL procedure successfully completed. 

Bạn cũng có thể tham gia xây dựng table thay vì sử dụng su bquery:

... 
    select count(*) into c 
    from table(i_itemname) t 
    join all_tables at on at.owner = t.column_value; 
... 

Tôi không rõ ràng bạn đang mặc đồng nào. (Nếu bạn không sử dụng bộ sưu tập cho bất cứ điều gì khác, bạn nên được tốt hơn chỉ cần tham gia các dữ liệu thô, nhưng tôi giả sử bộ sưu tập là có cho một lý do).


Như @haki đề cập trong các ý kiến, bạn cũng có thể làm:

... 
    select count(*) into c 
    from all_tables 
    where owner member of (i_itemname); 
... 

... chừng nào i_name và cột bạn đang so sánh với are the same type. Trong ví dụ của tôi, nó tìm thấy hàng không bởi vì tôi đang cố gắng so sánh nvarchar2 với varchar2, nhưng sẽ tìm thấy kết quả phù hợp nếu được xác định lại i_namevarchar2(512). Trong trường hợp của bạn có lẽ là tab.colnvarchar2.

+2

+1 Tôi nghĩ bạn cũng có thể sử dụng nó như thế này 'select count (*) từ all_tables, nơi chủ sở hữu thành viên của (i_itemname)'. – haki

+0

@haki - đẹp, tôi không nghĩ mình đã từng sử dụng nó. Đối với ví dụ của tôi, nó không tìm thấy kết quả phù hợp [vì loại không khớp] (http://docs.oracle.com/cd/E11882_01/server.112/e26088/conditions006.htm#sthref1966) - Tôi có 'i_type' là 'nvarchar2' nhưng' owner' là 'varchar2', nhưng nó gọn gàng nếu' i_type' được định nghĩa lại để khớp. (Tôi đã thêm điều đó vào câu trả lời của tôi, nhưng nếu bạn đăng câu trả lời của riêng mình, tôi sẽ xóa nó; không cố gắng lấy tín dụng!) –

Các vấn đề liên quan