代码之家  ›  专栏  ›  技术社区  ›  Rohith

Oracle错误ORA-22905:无法访问非嵌套表项中的行

  •  6
  • Rohith  · 技术社区  · 15 年前

    这是我编写的存储过程。在这个过程中,“p_subjectid”是从前端传递的一个数字数组。

    PROCEDURE getsubjects(p_subjectid subjectid_tab,p_subjects out refCursor) 
           as
    
           BEGIN
    
                open p_subjects for select * from empsubject where subject_id in
                (select column_value from table(p_subjectid));
                --select * from table(cast(p_subjectid as packg.subjectid_tab))
          END getsubjects;
    

    这就是我得到的错误。

    Oracle error ORA-22905: cannot access rows from a non-nested table item OR
    

    ORA-00902: invalid datatype .

    这就是“主体选项卡”的定义。

    type subjectid_tab is table of number index by binary_integer;
    

    有人能告诉我出了什么问题吗?我的程序有什么问题吗。

    5 回复  |  直到 13 年前
        1
  •  13
  •   Thorsten    15 年前

    您必须按照ammoQ的建议在“数据库级别”上声明类型:

    CREATE TYPE subjectid_tab AS TABLE OF NUMBER INDEX BY binary_integer;
    

    而不是在PL/SQL中声明类型。如果仅在PL/SQL块中声明类型,则SQL“引擎”将无法使用该类型。

        2
  •  3
  •   MT0    6 年前

    SELECT / INSERT UPDATE (etc)语句您正在SQL范围内工作,在Oracle 11g及以下版本中,您不能引用PL/SQL范围内定义的类型。( 注意:Oracle 12对此进行了更改,以便您可以引用PL/SQL类型。)

    TYPE subjectid_tab IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
    

    是关联数组,只能在PL/SQL范围中定义,因此不能在SQL语句中使用。

    您需要使用以下命令在SQL作用域中定义集合(而不是关联数组):

    CREATE TYPE subjectid_tab IS TABLE OF NUMBER;
    

    ( 注意:您不需要 INDEX BY 集合的子句。

    然后你可以做:

    OPEN p_subjects FOR
      SELECT *
      FROM   empsubject
      WHERE  subject_id MEMBER OF p_subjectid;
    

    OPEN p_subjects FOR
      SELECT *
      FROM   empsubject
      WHERE  subject_id IN ( SELECT COLUMN_VALUE FROM TABLE( p_subjectid ) );
    
        3
  •  2
  •   Nicolas    14 年前

    这是一个很好的解决方案。 如果所转换的类型位于pl/sql块的DECLARE部分,则不能使用表(cast())。 您确实需要使用CREATE TYPE my_TYPE[…]。否则,它将抛出“无法获取行[…]”异常。

        4
  •  2
  •   2 revs, 2 users 98%<br/>anon&#13;    6 年前

    DECLARE 
      TYPE number_table IS TABLE OF NUMBER;
      result_ids number_table := number_table();
    BEGIN
      /* .. bunch of code that uses my type successfully */ 
    
      OPEN ? AS 
      SELECT * 
      FROM TABLE(CAST(result_ids AS number_table)); /* BOOM! */
    END;
    
    

    当从java例程调用时,上述两种方法都会失败。我发现这是因为type number_表没有以可导出的方式定义,而不能从数据库中导出。这种类型在日常工作中非常有效。但只要您尝试执行以任何方式引用它的可返回记录集(包括在子句中?!?),您就会得到一个未定义的数据类型。

    CREATE TYPE myschema.number_table IS TABLE OF NUMBER; 然后从块中删除类型声明并使用模式级声明。使用模式限定符引用类型,以确保使用的是正确的类型。

        5
  •  1
  •   MT0    6 年前

    如果管道函数返回varchar2的rowtype,则定义一个类型(例如)

    CREATE OR REPLACE TYPE char_array_t is VARRAY(32) of varchar2(255);
    select * from table(cast(fn(x) as user_type_t ) );