Почему возникает ошибка: "PLS-00302: component must be declared", хотя указанное там имя существует?

Создаю свой тип данных:

create or replace type sh.itemobj is object (id int, memo varchar2 (64))
/
Type ITEMOBJ compiled

select sh.itemobj (1, 'memo') item from dual;

ITEM(ID, MEMO)
---------------------
ITEMOBJ(1, 'memo')

Никаких ошибок нет и можно им воспользоваться в запросе, но когда пробую в PL/SQL блоке:

declare 
    ret sh.itemobj;
begin 
    ret := sh.itemobj (1, 'memo');
end;
/ 

То получаю следующую ошибку:

Error report -
ORA-06550: line 2, column 12:
PLS-00302: component 'ITEMOBJ' must be declared

Почему эта ошибка, как её избежать?


Ответы (1 шт):

Автор решения: 0xdb

Причина ошибки довольна проста:

component 'ITEMOBJ' must be declared

В сообщении об ошибке не упоминается имя схемы. То есть, при разрешении полного имени был найден объект БД с именем SH, совпадающий с именем схемы. Далее, для найденного объекта SH идёт безуспешный поиск компонента с именем ITEMOBJ. Как идёт разрешение имён в PL/SQL и его различиях с SQL.

Найти такие объекты можно следующим запросом:

select object_name, object_type 
from user_objects where object_name=upper('sh')
/

OBJECT_NAME  OBJECT_TYPE 
------------ ------------
SH           SEQUENCE    

Тут единственное решение, или переименовать объект БД, или удалить его:

drop sequence sh
/
Sequence SH dropped.

declare 
    ret sh.itemobj;
begin 
    ret := sh.itemobj (1, 'memo');
end;
/ 
PL/SQL procedure successfully completed.
→ Ссылка