2013-04-24 80 views
5

我在oracle代码块中使用了集合,因为没有表变量(就像在MS SQL Server中一样)。Oracle集合中的where子句

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

我正在使用“BULK COLLECT INTO I_ITEMNAME”填充集合。
我想在SELECT查询的WHERE子句中使用此集合,但无法找到执行此操作的方法。目前我使用FOR循环和逐项获取项目。
我怎么能在WHERE子句事端像

SELECT * FROM TBL WHERE COL IN I_ITEMNAME直接使用集合?

谢谢

回答

9

不能将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 

,但你可以,如果它在架构级别申报,基本上是让SQL知道类型,不只是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. 

您也可以加入table结构,而不是使用苏bquery:

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

我不太清楚你是洞虽然。 (如果你没有使用这个集合来做其他事情,你最好只加入原始数据,但我认为这个集合是有原因的)。


由于@haki在评论中提到的,你也可以这样做:

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

...只要i_name和列你与are the same type比较。在我的示例中,它找到零行,因为我试图将nvarchar2varchar2进行比较,但如果将i_name重新定义为varchar2(512),则会发现匹配。无论如何,你的情况大概是tab.colnvarchar2

+2

+1我认为你也可以像这样使用它'select count(*)from all_tables where owner member(i_itemname)'。 – haki 2013-04-24 08:54:16

+0

@haki - 很好,我不认为我曾经使用过。对于我的例子,它找不到匹配[因为类型不匹配](http://docs.oracle.com/cd/E11882_01/server.112/e26088/conditions006.htm#sthref1966) - 我有'i_type'作为'nvarchar2',但'owner'是'varchar2',但是如果'i_type'被重新定义为匹配,那么它是整洁的。 (我已经将其添加到了我的答案中,但是如果您发布自己的答案,我会将其删除;不要试图信任!) – 2013-04-24 09:20:28