Ошибка Oracle ORA-22905: невозможно получить доступ к строкам из не вложенного элемента таблицы - PullRequest
8 голосов
/ 22 мая 2009

вот хранимая процедура, которую я написал. В этом процессе "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 as packg.subjectid_tab)» внутри табличной функции, как указано в комментарии ниже. Но я получаю другую ошибку: ORA-00902: invalid datatype.

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

type subjectid_tab is table of number index by binary_integer;

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

Ответы [ 5 ]

11 голосов
/ 10 сентября 2009

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

CREATE TYPE subjectid_tab AS TABLE OF NUMBER INDEX BY binary_integer;

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

2 голосов
/ 18 февраля 2010

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

2 голосов
/ 27 мая 2009

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

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

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

1 голос
/ 30 апреля 2018

Oracle имеет две области выполнения: SQL и PL / SQL. При использовании оператора SELECT / INSERT / UPDATE (и т. Д.) Вы работаете в области 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 ) );
1 голос
/ 26 мая 2009

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...