【问题标题】:Collection type as a cursor parameter集合类型作为游标参数
【发布时间】:2013-01-09 11:35:29
【问题描述】:

我需要做一个接收列表作为参数的游标。我试过这个:

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(实际上数据库是只读的)。

有什么可能的解决办法吗?

【问题讨论】:

标签: sql oracle plsql cursor


【解决方案1】:

您需要一种 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 行,这可能会导致计划不佳。

【讨论】:

  • PLS-00201:必须声明标识符 sys.DBMSOUTPUT_LINESARRAY :(
  • @user1961089 你用的是什么oracle版本?你应该能够使用你在select owner, type_name, coll_type, elem_type_name, upper_bound, length from all_coll_types where elem_type_name = 'VARCHAR2'看到的合适类型
【解决方案2】:

您需要使用查询单独创建type

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

请稍后再试。

【讨论】:

    【解决方案3】:

    这可能会有所帮助 - 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;
     /
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-10
      • 2018-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多