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

后端 未结 5 908
忘了有多久
忘了有多久 2020-12-11 16:35

here\'s the stored procedure i wrote.In this proc \"p_subjectid\" is an array of numbers passed from the front end.

PROCEDURE getsubjects(p_subjectid subject         


        
相关标签:
5条回答
  • 2020-12-11 17:14

    You have to declare the type on "the database level" as ammoQ suggested:

    CREATE TYPE subjectid_tab AS TABLE OF NUMBER INDEX BY binary_integer;
    

    instead of declaring the type within PL/SQL. If you declare the type just in the PL/SQL block, it won't be available to the SQL "engine".

    0 讨论(0)
  • 2020-12-11 17:22

    This is the good solution. You cannot use a table(cast()) if the type that you cast is in the DECLARE part of the pl/sql block. You REALLY need to use CREATE TYPE my_type [...]. Otherwise, it will throw the "cannot fetch row[...]" exception.

    0 讨论(0)
  • 2020-12-11 17:26

    Oracle has two execution scopes: SQL and PL/SQL. When you use a SELECT/INSERT/UPDATE (etc) statement you are working in the SQL scope and, in Oracle 11g and below, you cannot reference types that are defined in the PL/SQL scope. (Note: Oracle 12 changed this so you can reference PL/SQL types.)

    TYPE subjectid_tab IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
    

    Is an associative array and can only be defined in the PL/SQL scope so cannot be used in SQL statements.

    What you want is to define a collection (not an associative array) in the SQL scope using:

    CREATE TYPE subjectid_tab IS TABLE OF NUMBER;
    

    (Note: you do not need the INDEX BY clause for a collection.)

    Then you can do:

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

    or

    OPEN p_subjects FOR
      SELECT *
      FROM   empsubject
      WHERE  subject_id IN ( SELECT COLUMN_VALUE FROM TABLE( p_subjectid ) );
    
    0 讨论(0)
  • 2020-12-11 17:30

    you have to cast the results of the pipelined query so:

    If your pipelined function returns a rowtype of varchar2 then define a type (for example )

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

    will now work.

    0 讨论(0)
  • 2020-12-11 17:35

    I just had this problem yesterday.

    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;
    
    

    This fails in both of the ways you described earlier when called from a java routine. I discovered this was due to the fact that the type number_table is not defined in an exportable manner than can be shipped off the database. The type works great internally to the routine. But as soon as you try to execute a returnable recordset that references it in any way (including IN clauses?!?) you get a datatype not defined.

    So the solution really is CREATE TYPE myschema.number_table IS TABLE OF NUMBER; Then drop the type declaration from your block and use the schema level declaration. Use the schema qualifier to reference the type just to be sure you are using the right one.

    0 讨论(0)
提交回复
热议问题