PLS-00201 标识符必须声明为引用用户定义类型为 SYS

Posted

技术标签:

【中文标题】PLS-00201 标识符必须声明为引用用户定义类型为 SYS【英文标题】:PLS-00201 identifier must be declared referencing user defined type as SYS 【发布时间】:2015-03-09 22:29:28 【问题描述】:

我的包创建脚本中某些定义的类型有问题 -

对于某些类型,我收到以下信息

PLS-00201 identifier must be declared 

例如;

Error(7,23): PLS-00201: identifier 'another_schema.some_table_type' must be declared
Error(8,23): PLS-00201: identifier 'another_schema.some_object_type' must be declared

我应该注意我正在更改这些脚本 - 之前运行良好 - 以前它们作为脚本所有者运行,现在只是一个容器模式/用户 - 并且创建脚本作为 SYS 执行。 (它是一个开发数据库,​​到目前为止,他们还没有为我创建一个用户来执行此操作,而不是 SYS)

(之前编译的包 - 当以具有适当权限的架构所有者身份运行时。)

此包(以及各种其他对象、视图过程和函数)访问其架构中的对象以及另一个架构中的对象。

在这种情况下 - 问题在于引用架构中的一些定义的类型(和类型表) - 我得到 PLS-00201 错误。

在下面的代码中,编译时会为引用生成错误;

      l_tc_data       another_schema.some_table_type := another_schema.some_table_type();
      l_tc_obj        another_schema.some_object_type;

但不是;

      l_loc_t        another_schema.location_ref_t; 

它们在相同的“其他”模式中。

create or replace PACKAGE BODY  example_schema.example_pkg 
AS
function getSomeData (p_project in varchar2, p_start_date in date, p_end_date in date, p_timezone in varchar2 := 'UTC')
return fancydatatabletype is
      l_cursor        SYS_REFCURSOR;
      l_tsdata        fancydatatabletype := fancydatatabletype();

      l_tc_data       another_schema.some_table_type := another_schema.some_table_type();
      l_tc_obj        another_schema.some_object_type;

      t_data          fancydatatype;
      l_project       VARCHAR2(20);
      l_timezone      VARCHAR2(40);
      l_start         DATE;
      l_end           DATE;

      l_loc_t        another_schema.location_ref_t; 
BEGIN
    l_tc_obj := another_schema.some_object_type(null, 1, 2, 3, 'test');

    -- .... more stuff
END getSomeData;

所以我的问题是; 1.这可能是特权问题吗? (以 SYS 身份运行) 2.我应该看哪些其他可能会产生此错误的东西? (因为它们确实存在)

我可以成功查询类型,所以它们确实存在,名称相同,用户(在本例中为 SYS)可以“看到”它们;

select * from ALL_TYPES where type_name like 'some_table_type%';

我知道我是愚蠢的、盲目的,或者只是在我的 Oracle 技能的限制下一无所知 - 所以希望有人能帮助我解决这个问题并在下一次学习!

【问题讨论】:

你能从匿名块而不是包中引用类型吗?有效和无效的类型的权限是如何分配的——分配给公共的、分配给角色的、直接分配给 SYS 的? (如果您有 SYS 访问权限,您不能创建自己的用户,还是这是一个流程问题?) 【参考方案1】:

引用的对象归 ANOTHER_SCHEMA 所有。您正试图在EXAMPLE_SCHEMA 拥有的PL/SQL 中使用它们。所以最可能的解释是两种模式之间的授权。

为了在代码中使用它们,ANOTHER_SCHEMA 必须直接授予EXAMPLE_SCHEMA 权限,即通过名称而不是通过角色授予权限。这是由于 Oracle 的安全模型的工作方式。

您可以像这样检查现有的赠款:

select table_name as object_name
       , privilege
       , grantor
from dba_tab_privs
where grantee = 'EXAMPLE_SCHEMA'
and table_owner = 'ANOTHER_SCHEMA'
/

【讨论】:

谢谢 - 它确实缺少明确的 EXECUTE 授权。我只是从收到的错误中没想到它!非常感谢! @bbaley 是的,一些 Oracle 错误消息相当模糊。从好的方面来说,现在你知道了,下次你会立即发现它;)

以上是关于PLS-00201 标识符必须声明为引用用户定义类型为 SYS的主要内容,如果未能解决你的问题,请参考以下文章

PLS-00201:标识符必须在过程中声明

PLS-00201:必须声明标识符“ISDATE”

必须声明错误 PLS-00201 标识符

PL SQL,错误(32,43):PLS-00201:必须声明标识符“HR”

Oracle TYPE 声明抛出错误 PLS-00201 - 必须声明标识符

PLS-00201:必须声明标识符“schema.cursorname”