无法将数据添加到Oracle自定义记录 - 错误 - 下标超出计数

时间:2014-11-05 17:48:41

标签: oracle user-defined-types

我创建了自定义Oracle记录类型,我试图填充一些值并尝试在另一个存储过程中访问相同的内容(实际上我将从Java调用 - 我在Java中也遇到了同样的错误)但是我我收到“Subscript beyond count”错误消息。

我只是存储过程的初学者。 以下是我的所作所为。

Oracle客户记录类型

create or replace type learnerMapCustomRecord as object(activityName varchar2(20),activityDescn varchar2(20));

create or replace type learnerMapCustomRecordTable as table of learnerMapCustomRecord;

存储过程以将值填充到记录类型

create or replace PROCEDURE getLearnerMapDetails(learnerMapCustomRecord out learnerMapCustomRecordTable) as 
cursor c1 is select object_name,status from user_objects  where rownum <= 2;
c c1%rowtype;
i number:=1;
begin
  learnerMapCustomRecord := learnerMapCustomRecordTable();
  open c1;
  loop
    fetch c1 into c;
    EXIT WHEN C1%NOTFOUND;
    dbms_output.put_line(c.object_name||'==>'||c.status);
  --  learnerMapCustomRecord.extend;
    learnerMapCustomRecord(I).activityName:=C.OBJECT_NAME;
    learnerMapCustomRecord(i).activityDescn:=c.status;
    i:=i+1;
  end loop; 
end;

从我调用上述SP的存储过程来访问自定义记录类型列表。

create or replace procedure data_collection_extract as
learnerMapCustomRecord learnerMapCustomRecordTable;
begin
  getLearnerMapDetails(learnerMapCustomRecord);
  for i in learnerMapCustomRecord.first..learnerMapCustomRecord.last
  LOOP
   dbms_output.put_line(learnerMapCustomRecord(i).activityName||'==>'||learnerMapCustomRecord(i).activityDescn);
  end loop; 
end;

set serveroutput on;
exec data_collection_extract();
/
show error;
Error report -
ORA-06533: Subscript beyond count
ORA-06512: at "FOL_DEV.GETLEARNERMAPDETAILS", line 13
ORA-06512: at "FOL_DEV.DATA_COLLECTION_EXTRACT", line 4
ORA-06512: at line 1
06533. 00000 -  "Subscript beyond count"
*Cause:    An in-limit subscript was greater than the count of a varray
           or too large for a nested table.
*Action:   Check the program logic and explicitly extend if necessary.

你能解释一下我做错了吗?

1 个答案:

答案 0 :(得分:0)

几个问题:

  1. 你没有扩展你的收藏(尽管.extend()方法已经存在......已被注释掉。)
  2. 您没有实例化对象类learnerMapCustomRecord
  3. 您没有关闭光标c1
  4. 您的输出参数与您的类名相同,因为默认标识符范围分辨率,实际上会使对象类的实例化变得更加困难。
  5. 你通过使用逐行fetch来进行SQL引擎的过多往返(也为自己做太多工作),你可以在那里进行常规游标for - 循环或批量获取。
  6. 解决方案:

    create or replace PROCEDURE getLearnerMapDetails(theOutput out learnerMapCustomRecordTable)
    as
      cursor c1 is select object_name,status from user_objects  where rownum <= 2;
      c c1%rowtype;
    begin
      theOutput := learnerMapCustomRecordTable();
      open c1;
      loop
        fetch c1 into c;
        EXIT WHEN C1%NOTFOUND;
        dbms_output.put_line(c.object_name||'==>'||c.status);
        theOutput.extend();
        theOutput(theOutput.last) := new learnerMapCustomRecord(
            activityName => c.object_name,
            activityDescn => c.status
        );
      end loop; 
      close c1;
    end;
    

    ...并且SQL Engnie往返减少...

    create or replace PROCEDURE getLearnerMapDetails(theOutput out learnerMapCustomRecordTable)
    as
      cursor c1 is select object_name,status from user_objects  where rownum <= 2;
    begin
      theOutput := learnerMapCustomRecordTable();
      for c in c1 loop
        dbms_output.put_line(c.object_name||'==>'||c.status);
        theOutput.extend();
        theOutput(theOutput.last) := new learnerMapCustomRecord(
            activityName => c.object_name,
            activityDescn => c.status
        );
      end loop; 
    end;
    

    ......如果你想做一个&#34;硬汉的方式&#34;,那么你可以这样做......

    create or replace PROCEDURE getLearnerMapDetails(theOutput out learnerMapCustomRecordTable) as
    begin
        select new learnerMapCustomRecord(
            activityName => object_name,
            activityDescn => status
        )
        bulk collect into theOutput
        from user_objects
        where rownum <= 2;
    end;
    

    享受。