Plsql ORA-21700从包用户定义表中选择

Plsql ORA-21700从包用户定义表中选择,plsql,package,user-defined-types,Plsql,Package,User Defined Types,我正在创建一个Oracle包(MyPackage),其中有一个自定义类型记录(ObjData)的公共自定义类型表(ObjData),它将用作包函数之一(Calculate)的IN参数: 我删除了代码中的bug,在光标的第二行(用代码标记)出现了错误: ORA-21700:对象不存在或已标记为删除oracle 我正在使用此数据执行我的包: CREATE TABLE TestTable (d date DEFAULT DATE '0001-01-01', v number(9, 4)); INSER

我正在创建一个Oracle包(
MyPackage
),其中有一个自定义类型记录(
ObjData
)的公共自定义类型表(
ObjData
),它将用作包函数之一(
Calculate
)的IN参数:

我删除了代码中的bug,在光标的第二行(用代码标记)出现了错误:

ORA-21700:对象不存在或已标记为删除oracle

我正在使用此数据执行我的包:

CREATE TABLE TestTable (d date DEFAULT DATE '0001-01-01', v number(9, 4));
INSERT INTO TestTable VALUES (DATE '2015-01-01', 2.1);
INSERT INTO TestTable VALUES (DATE '2015-01-08', 3.1);
INSERT INTO TestTable VALUES (DATE '2015-01-15', 4.1);
INSERT INTO TestTable VALUES (DATE '2015-01-22', 5.1);
INSERT INTO TestTable VALUES (DATE '2015-01-29', 6.1);
INSERT INTO TestTable VALUES (DATE '2015-02-05', 7.1);
下面是运行测试的代码:

CREATE OR REPLACE PROCEDURE TestMyPackage AS
    res MyPackage.ObjDataCollection;
    counter number(9, 4);
BEGIN
    SELECT d, v
        BULK COLLECT INTO res
        FROM TestTable
        ORDER BY v;
    counter := MyPackage.Calculate(res);
END TestMyPackage;

为什么我会收到这个ORA-21700异常?

由于这是一项由于日期而导致的任务,我最终按照他的一条评论中的建议,通过在模式级别创建用户定义的类型和表来修复它。谢谢你的努力

PACKAGE BODY MyPackage AS
    FUNCTION Calculate(
        DataSource IN ObjDataCollection
    ) RETURN number IS
        res BINARY_FLoAT:= 0;
        dateStart date;
        dsv ObjData;
        copy_of_DataSource ObjDataCollection;

        procedure sortCollection(toSort in out ObjDataCollection)
        is
          type idx_coll  is table of ObjData;
          type sort_help is table of idx_coll index by varchar2(16 char);
           v_sort sort_help;
           v_temp varchar2(16);
           v_result ObjDataCollection := new ObjDataCollection();
           v_cnt PLS_INTEGER := 0;
        begin
          for i in nvl(toSort.first,1) .. nvl(toSort.last,-1) loop
              v_temp := to_char(toSort(i).t,'yyyymmddhh24miss');
              if v_sort.exists(v_temp) then
                 v_sort(v_temp).extend(1);
                 v_sort(v_temp)(v_sort(v_temp).count) := toSort(i);
              else
                 v_sort(v_temp) := idx_coll(toSort(i));
              end if;
          end loop;
          v_result.extend(toSort.count);
          v_temp := v_sort.first;
          while v_temp is not null loop
              for i in nvl(v_sort(v_temp).first,1) .. nvl(v_sort(v_temp).last,-1) loop
                 v_cnt := v_cnt +1;
                 v_result(v_cnt) := v_sort(v_temp)(i);
              end loop;
              v_temp := v_sort.next(v_temp);
          end loop;
          toSort := v_result;
        end;

    BEGIN
        -- some irrelevant code
        copy_of_DataSource := DataSource;
        dateStart := DATE '2015-01-01';
        sortCollection(copy_of_DataSource);
        for i in nvl(copy_of_DataSource.first,1) .. nvl(copy_of_DataSource.last,-1) loop
          if copy_of_DataSource(i).t > dateStart then
             res := res +  copy_of_DataSource(i).v;
             dbms_output.put_line(copy_of_DataSource(i).t);
          end if;
        end loop;
        -- some irrelevant code
        return res;
    END Calculate;
END MyPackage;

因为这不是我想要的,所以我不会将任何答案标记为正确。

因为这是一项因日期而产生的任务,我最终按照他的一条评论中的建议,通过在模式级别创建用户定义的类型和表来修复它。谢谢你的努力


因为这不是我想要的,所以我不会将任何答案标记为正确。

得到了相同的问题,并通过执行以下步骤解决了它:

  • 放置定义了类型的包
  • 使用该类型删除包
  • 使用类型编译包
  • 编译目标包

  • 在一个包含类型/常量的包中添加新常量后,我得到了这个ORA-21700。我想依赖关系可能存在一些内部问题,但我没有挖掘太多。

    也遇到了同样的问题,并通过执行以下步骤解决了它:

  • 放置定义了类型的包
  • 使用该类型删除包
  • 使用类型编译包
  • 编译目标包

  • 在一个包含类型/常量的包中添加新常量后,我得到了这个ORA-21700。我想依赖关系可能存在一些内部问题,但我没有挖掘太多。

    在编译包时,您应该会遇到其他错误(PLS-00642)。因为无法在select语句中使用本地集合类型。创建架构级对象并在包中使用它们。创建类型ObjData作为对象(t date,v number(9,4)),创建类型ObjDataCollection作为ObjData表;我需要将其作为一个独立的包分发,这就是为什么我有输入数据模型,而不是直接从数据库读取。不要在计算函数中使用游标。在包编译时,您应该会遇到其他错误(PLS-00642)。因为无法在select语句中使用本地集合类型。创建架构级对象并在包中使用它们。创建类型ObjData作为对象(t date,v number(9,4)),创建类型ObjDataCollection作为ObjData表;我需要将其作为一个独立的包分发,这就是为什么我有输入数据模型,而不是直接从数据库中读取。不要在计算函数中使用游标。我已经考虑过这个选项,但数据排序也是一个要求。但您已经以正确的顺序将数据提取到集合中。是的,我有,但作为一个包,客户希望数据和业务逻辑层独立于使用索引为的表的otherSort集合。无法在包中添加用户类型表的索引。我已经考虑过此选项,但数据排序也是一项要求。但您已按正确的顺序将数据提取到集合中。是的,我这样做了,但作为一个包,客户希望数据和业务逻辑层独立于使用索引为的表的otherSort集合。无法在包中添加用户类型表的索引。
    PACKAGE BODY MyPackage AS
        FUNCTION Calculate(
            DataSource IN ObjDataCollection
        ) RETURN number IS
            res BINARY_FLoAT:= 0;
            dateStart date;
            dsv ObjData;
            copy_of_DataSource ObjDataCollection;
    
            procedure sortCollection(toSort in out ObjDataCollection)
            is
              type idx_coll  is table of ObjData;
              type sort_help is table of idx_coll index by varchar2(16 char);
               v_sort sort_help;
               v_temp varchar2(16);
               v_result ObjDataCollection := new ObjDataCollection();
               v_cnt PLS_INTEGER := 0;
            begin
              for i in nvl(toSort.first,1) .. nvl(toSort.last,-1) loop
                  v_temp := to_char(toSort(i).t,'yyyymmddhh24miss');
                  if v_sort.exists(v_temp) then
                     v_sort(v_temp).extend(1);
                     v_sort(v_temp)(v_sort(v_temp).count) := toSort(i);
                  else
                     v_sort(v_temp) := idx_coll(toSort(i));
                  end if;
              end loop;
              v_result.extend(toSort.count);
              v_temp := v_sort.first;
              while v_temp is not null loop
                  for i in nvl(v_sort(v_temp).first,1) .. nvl(v_sort(v_temp).last,-1) loop
                     v_cnt := v_cnt +1;
                     v_result(v_cnt) := v_sort(v_temp)(i);
                  end loop;
                  v_temp := v_sort.next(v_temp);
              end loop;
              toSort := v_result;
            end;
    
        BEGIN
            -- some irrelevant code
            copy_of_DataSource := DataSource;
            dateStart := DATE '2015-01-01';
            sortCollection(copy_of_DataSource);
            for i in nvl(copy_of_DataSource.first,1) .. nvl(copy_of_DataSource.last,-1) loop
              if copy_of_DataSource(i).t > dateStart then
                 res := res +  copy_of_DataSource(i).v;
                 dbms_output.put_line(copy_of_DataSource(i).t);
              end if;
            end loop;
            -- some irrelevant code
            return res;
        END Calculate;
    END MyPackage;