我需要做一个接收列表作为参数的游标。我试过这个:
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 :(得分:1)
您需要使用查询
分别创建type
CREATE OR REPLACE type array_t as table of varchar2(50);
请在此之后尝试。
答案 1 :(得分:0)
您需要SQL类型而不是pl / 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大概有多少行在数组中。放一个有代表性的数字,或者oracle会假设数组包含@ 8k行,这可能导致计划不佳。
答案 2 :(得分:0)
这可能会有所帮助 - Oracle 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;
/