Oracle error ORA-22905: не удается получить доступ к строкам из не вложенного элемента таблицы

вот хранимая процедура, которую я написал.В этом proc "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

как я видел в другом посте, я попробовал кастинг " cast(p_subjectid как packg.subjectid_tab) " внутри функции таблицы, как указано в комментарии ниже.Но я получаю еще одну ошибку:ORA-00902: invalid datatype.

и это определение "subjectid_tab".

type subjectid_tab is table of number index by binary_integer;

Can кто-нибудь, пожалуйста, скажите мне, в чем ошибка.Что-то не так с моей процедурой.

5 ответов


вы должны объявить тип на "уровне базы данных", как предложил ammoQ:

CREATE TYPE subjectid_tab AS TABLE OF NUMBER INDEX BY binary_integer;

вместо объявления типа в PL / SQL. Если вы объявите тип только в блоке PL/SQL, он не будет доступен для SQL "engine".


Это хорошее решение. Вы не можете использовать таблицу (cast ()), если тип, который вы бросаете, находится в объявленной части блока pl/sql. Вам действительно нужно использовать CREATE TYPE my_type [...]. В противном случае он будет бросать "не удается получить строку [...]" исключение.


у меня только вчера была эта проблема.

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. Я обнаружил, что это связано с тем, что тип number_table не определен экспортируемым способом, чем может быть отправлен из базы данных. Тип отлично работает внутри рутины. Но как только вы попытаетесь выполнить возвращаемый набор записей, который ссылается на него каким-либо образом (в том числе в предложениях?!?) вы получаете тип данных не определен.

таким образом, решение действительно CREATE TYPE myschema.number_table IS TABLE OF NUMBER; затем удалите объявление типа из своего блока и используйте объявление уровня схемы. Используйте квалификатор схемы для ссылки на тип, чтобы убедиться, что вы используете правильный.


Oracle имеет две области выполнения: SQL и PL/SQL. Когда вы используете 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 ) );

вы должны привести результаты конвейерного запроса так:

Если ваша конвейерная функция возвращает тип строки varchar2, то определите тип (например )

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

теперь будет работать.