2013-01-09 62 views
1

我需要做一個遊標,接收一個列表作爲參數。我已經試過這樣:收集類型作爲遊標參數

declare 

type array_t is table of varchar(50); -- //also tried varray(10) instead of table 

cursor c_cursor (p_list array_t) is 
select 
    field_1 
from 
    table_1 
where 
    field_2 in p_list; 

a_list array_t; 

begin 
    a_list := array_t('aaa', 
     'bbb', 
     'cccc', 
     'ddd'); 

    for v_cursor in c_cursor(a_list) loop 
     dbms_output.put_line(v_cursor.field_1); 
    end loop; 
end; 

,我得到以下錯誤

ORA-06550: line 11, column 21: 
PLS-00642: local collection types not allowed in SQL statements 

我已閱讀有關使用CREATE OR REPLACE方法,但我不能在這種情況下使用CREATE OR REPLACE(實際上該數據庫是隻讀的)。

有沒有可能的解決辦法?

+0

請添加查詢的預期輸出。 – TechDo

+0

以下是一些示例:http://stackoverflow.com/questions/4249010/in-pl-sql-take-a-table-as-parameter-filter-it-and-return-it – Art

回答

0

您需要一個不是pl/sql的SQL類型,然後使用table語法來使用它。

正如你所說你不能創建一個,請嘗試內置於DBMS_OUTPUT上的一個。

SQL> create table table_1(field_1 varchar2(20), field_2 varchar2(20)); 

Table created. 

SQL> insert into table_1 values ('test', 'aaa'); 

1 row created. 

SQL> insert into table_1 values ('test2', 'cccc'); 

1 row created. 

SQL> insert into table_1 values ('test3', 'x'); 

1 row created. 

SQL> commit; 

Commit complete. 

SQL> set serverout on 
SQL> declare 
    2 cursor c_cursor (p_list sys.DBMSOUTPUT_LINESARRAY) is 
    3 select /*+ cardinality(p, 10) */ 
    4  field_1 
    5 from 
    6  table_1 t 
    7  inner join table(p_list) p 
    8    on t.field_2 = p.column_value; 
    9 
10 a_list sys.DBMSOUTPUT_LINESARRAY; 
11 
12 begin 
13  a_list := sys.DBMSOUTPUT_LINESARRAY('aaa', 
14   'bbb', 
15   'cccc', 
16   'ddd'); 
17 
18  for v_cursor in c_cursor(a_list) loop 
19   dbms_output.put_line(v_cursor.field_1); 
20  end loop; 
21 end; 
22/
test 
test2 

/*+ cardinality(p, 10) */提示就是要告訴甲骨文大概多少行怎麼會在數組中。放一個有代表性的數字,否則oracle將假定數組包含@ 8k行,這可能會導致計劃不佳。

+0

PLS-00201:標識符sys。 DBMSOUTPUT_LINESARRAY必須聲明:( – Enrique

+0

@ user1961089你在什麼oracle版本?你應該能夠使用一個合適的類型,你可以看到'select owner,type_name,coll_type,elem_type_name,upper_bound,length from all_coll_types where elem_type_name ='VARCHAR2' ' – DazzaL

+0

我找到了合適的類型,非常感謝。 – Enrique

1

您需要單獨創建type使用查詢

CREATE OR REPLACE type array_t as table of varchar2(50); 

請以後再試。

0

這可能會幫助 - 甲骨文的PL/SQL:

DECLARE 
    Type t_EmpNoArr IS VARRAY(20000) OF NUMBER(10) ; 
    v_RetVal t_EmpNoArr:= t_EmpNoArr(); 
    -- 
    FUNCTION retArray return t_EmpNoArr 
    IS 
    v_empnoArr t_EmpNoArr:= t_EmpNoArr(); 
    BEGIN 
    FOR i IN (SELECT empno FROM scott.emp) 
    LOOP 
     v_empnoArr.extend() ; 
     v_empnoArr(v_empnoArr.count):= i.empno ; 
    END LOOP; 
    -- 
    FOR j IN 1..v_empnoArr.COUNT() LOOP 
     DBMS_OUTPUT.PUT_LINE(v_empnoArr(j)); 
    END LOOP; 
    -- 
    RETURN v_empnoArr; 
END retArray; 
-- 
BEGIN 
    v_RetVal:= retArray(); 
END; 
/