PLS-00201:必须声明标识符'TYPE'



我正在以user1的身份连接到Oracle数据库。在数据库中,user2存在并且具有包含两个存储过程proc1proc2的包pack1

我正试图调用这些过程,但我遇到了前面提到的错误。该错误提到在Types中定义的"type1"。

经过一些研究,有人建议检查特权,但这些似乎没问题。我使用的是Oracle SQL Developer,当我在pack1type1上单击"grants"时,我的用户同时具有EXECUTE和DEBUG权限。

我以为这是代码中的一个错误,但这会引发另一个错误。我曾想过为这个包创建一个同义词,因为我读到这些可能会有所帮助,但我没有必要这样做,在我提出要求之前,我想用尽我所有的选择。

当我尝试运行这些存储过程时,我尝试使用我准备好的调用和SQL Developer创建的默认调用。有趣的是,当我运行代码时,会抛出上面提到的错误。当我运行"默认"代码时,我会得到"绝对URI中的相对路径"错误。

有什么我可能错过的吗?

这是我用来调用过程的代码。

DECLARE
ClientData type1;
BEGIN
pack1.proc1(param1,param2,ClientData);
FOR i IN 1..ClientData.LAST LOOP
DBMS_OUTPUT.PUT_LINE(ClientData(i).kid ||' '...;
--DBMS_OUTPUT.PUT_LINE(ClientData(i).portfolioName);
--DBMS_OUTPUT.PUT_LINE(ClientData(i).clientCategory);
--DBMS_OUTPUT.PUT_LINE(ClientData(i).typ_pf);
--DBMS_OUTPUT.PUT_LINE(ClientData(i). ptf_ccy);
END LOOP;
END;

编辑1:这是完整的错误:

ORA-06550: row 2, column 14:
PLS-00201: identifier 'SYSADMIN(user2).CLIENTDATAINSTRESB_A(type1)' must be declared
ORA-06550: row 2, column 14:
PL/SQL: Item ignored
ORA-06550: row 4, column 53:
PLS-00320: the declaration of the type of this expression is     incomplete or malformed
ORA-06550: row 4, column 1:
PL/SQL: Statement ignored
ORA-06550: row 5, column 13:
PLS-00320: the declaration of the type of this expression is incomplete or malformed
ORA-06550: row 5, column 1:
PL/SQL: Statement ignored
06550. 00000 -  "line %s, column %s:n%s"
*Cause:    Usually a PL/SQL compilation error.
*Action:

在正常情况下,我会包括程序的主体,然而,这是业务,因此我不能分享
据我所知,在调用开始时,声明失败,因此会导致其余错误,因为这些错误对应于调用"type1"的位置
为了进一步解释什么是"type1",它是对表("type2")的引用。它由以下代码创建:

create or replace TYPE type1 IS TABLE OF type2;

编辑2正如@Alex Poole所建议的,我已经修改了我的声明:

DECLARE
ClientData user2.type1;

然而,它再现了相同的错误:

PLS-00201: identifier 'user2.type1' must be declared

编辑3
错误的名称是由我伪造代码造成的,它被修复了。
包和这两种类型都归user2所有。当我连接到数据库时,从我的角度看不到任何东西。没有表、包或类型。只有当我浏览、、Other users并查看user2的透视图时,我才能看到所需的过程。
此外,我确信我对所有必需的对象都有权限(EXECUTE&DEBUG)。那就是包和定义的类型。
当谈到如何授予权限时,有办法检查吗?我使用了命令

SELECT * FROM USER_TAB_PRIVS;

将user2列为授予人和所有者,将user1列为被授予人
EDIT 4
这是SELECT*FROM USER_TAB_PRIVS的结果;

GRANTEE OWNER   TABLE_NAME  GRANTOR PRIVILEGE   GRANTABLE  HIERARCHY    COMMON  TYPE
USER1   USER2   TYPE2       USER2   DEBUG       NO         NO           NO  TYPE
USER1   USER2   TYPE2       USER2   EXECUTE     NO         NO           NO  TYPE
USER1   USER2   TYPE1       USER2   DEBUG       NO         NO           NO  TYPE
USER1   USER2   TYPE1       USER2   EXECUTE     NO         NO           NO  TYPE
USER1   USER2   PACK1       USER2   DEBUG       NO         NO           NO  PACKAGE
USER1   USER2   PACK1       USER2   EXECUTE     NO         NO           NO  PACKAGE
PUBLIC  SYS     USER1       USER1   INHERIT PRIVILEGES  NO  NO  NO  USER

编辑5:修复了从小写到大写的结果表。然而,正如建议的那样,我仔细检查了包和类型的名称,它们确实是大写的。

我认为您的主要问题是类型的定义。

你必须检查哪一行使用了哪种类型。

你应该拥有的:

user1->NO TYPES,一个调用user2填充的包

user2->Type1,Pack1,Proc1

示例:

-- Create your type on schema user2
CREATE OR REPLACE TYPE USER2.TestType AS OBJECT
(
NEWATTRIB1 VARCHAR2(1000)
)
/
-- Create your package at user2
CREATE OR REPLACE PACKAGE user2.TestPackage AS
FUNCTION MyFunction(Param1 IN TestType) RETURN TestType;
END TestPackage;
/
CREATE OR REPLACE PACKAGE BODY user2.TestPackage AS
FUNCTION MyFunction(Param1 IN TestType) RETURN TestType IS
BEGIN
RETURN Param1;
END;
END TestPackage;
/
-- Grant rights user1 (run with user2)
GRANT ALL ON TestType TO User1 WITH GRANT OPTION;
GRANT EXECUTE ON TestPackage TO User1 WITH GRANT OPTION;
-- Call proc from User1
declare
tmp USER2.TestType;
tmp2 USER2.TestType;
begin
tmp := USER2.TestType('Mr.Smith');
tmp2 := USER2.TESTPACKAGE.MYFUNCTION(tmp);
dbms_output.put_line('tmp: ' || tmp.NEWATTRIB1);
dbms_output.put_line('tmp2: ' || tmp2.NEWATTRIB1); 
end;

请记住:两种类型永远不一样!如果在架构中使用类型,则不允许在另一个架构中定义类似的类型来检索对象。您必须在另一个模式中显式命名类型(=user2.type1)。您必须将权限授予想要使用该类型的模式/用户(在您的示例中,授予类型和包权限)。

作为现有项目中的故障排除,您可以逐步检查:

  1. 使用user1登录
  2. 编写一些使用类型的plsql

    declare
    tmp user2.type1;
    begin
    tmp := user2.type1('Mr.Smith');
    -- if this works, your type-privs are correct.
    end;
    
  3. 编写一些使用包的plsql

相关内容

最新更新