简体   繁体   English

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

[英]PLS-00201: identifier 'TYPE' must be declared

I'm connecting to an Oracle database as user1 . 我以user1身份连接到Oracle数据库。 Within the database, user2 exists and has a package pack1 which contains two stored procedures, proc1 and proc2 . 在数据库中, user2存在并且有一个包pack1 ,它包含两个存储过程proc1proc2

I'm trying to call those procedures, but I'm getting the aforementioned error. 我试图调用这些程序,但我收到了上述错误。 The error mentions 'type1' that is defined in Types. 该错误提到了类型中定义的'type1'。

After some research, it was suggested to check privileges, however those seem to be fine. 经过一些研究,有人建议检查权限,但这些似乎没问题。 I'm using Oracle SQL Developer and when I click "grants" on the pack1 and type1 , my user has both EXECUTE and DEBUG privileges. 我正在使用Oracle SQL Developer,当我在pack1type1上单击“grants”时,我的用户具有EXECUTE和DEBUG权限。

I thought it was an error in the code, but that would throw a different error. 我认为这是代码中的错误,但这会引发不同的错误。 I thought about creaing an synonym for the package as I have read that those can help, but I don't have neccesary right to do so and before I ask, I wanted to exhaust all my options. 我想到了创建包的同义词,因为我已经读过那些可以提供帮助,但我没有必要这样做,在我问之前,我想用尽所有选择。

I have tried to use both my prepared call and a default one created by SQL Developer when I try to run those stored procedures. 当我尝试运行这些存储过程时,我尝试使用我准备好的调用和SQL Developer创建的默认调用。 Interestingly, when I run my code, mentioned error is thrown. 有趣的是,当我运行我的代码时,会提到错误。 When I run the "default" code I get "Relative path in absolute URI" error. 当我运行“默认”代码时,我得到“绝对URI中的相对路径”错误。

Is there anything I could have missed? 有什么我可以错过的吗?

This is the code I'm using to call the procedure. 这是我用来调用该过程的代码。

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;

EDIT 1: here is the full error: 编辑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:

Under normal circumstances, I would include the body of the procedure, however, it is business and therefore something I cannot share. 在正常情况下,我会包括程序的主体,但是,这是业务,因此我无法分享。
From what I understand, on the beginning of the call, declaration failes and therefore it results in the rest of the errors, since those correspod to the places where the 'type1' is called. 根据我的理解,在调用开始时,声明会失效,因此会导致其余的错误,因为这些错误会导致调用'type1'的地方。
To further explain what 'type1' is, it is a refference to a table ('type2'). 为了进一步解释'type1'是什么,它是对表('type2')的引用。 It is created by following code: 它由以下代码创建:

create or replace TYPE type1 IS TABLE OF type2;

EDIT 2 as @Alex Poole suggested, I've modified my declaration: 编辑2 @Alex Poole建议,我修改了我的声明:

DECLARE
ClientData user2.type1;

however, it reproduced the same error: 但是,它再现了同样的错误:

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

EDIT 3 编辑3
The incorrect names were caused by me forgeting to sterilize the code, it was fixed. 不正确的名字是由我伪造代码消毒引起的,它是固定的。
The packages and the both types are owned by the user2. 包和两种类型都归user2所有。 When I connect to the database, I don't see anything from my perspective. 当我连接到数据库时,我从我的角度看不到任何东西。 No tables, packages or types. 没有表格,包裹或类型。 Only when I browse ,,Other users" and look into perspective of user2, I can see the required procedures. 只有当我浏览,其他用户“并查看user2的视角时,我才能看到所需的程序。
Also, I am positive that I have privileges (EXECUTE & DEBUG) to all required objects. 另外,我很肯定我对所有必需的对象都有权限(EXECUTE&DEBUG)。 That is packages, and defined types. 那就是包和定义的类型。
When talking about how the privileges were granted, is there a way to check that? 在谈论如何授予权限时,有没有办法检查? I used command 我用命令

SELECT * FROM USER_TAB_PRIVS;

That lists user2 as a Grantor and Owner and user1 as a Grantee 将user2列为Grantor和Owner,将user1列为Grantee
EDIT 4 编辑4
This is the outcome of SELECT * FROM USER_TAB_PRIVS; 这是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

EDIT 5: Fixed the outcome table from lower-case to upper-case. 编辑5:修正了从小写到大写的结果表。 As suggested however, I double-checked the names of the package and the Types, they are indeed in upper case. 然而,正如所建议的那样,我仔细检查了包的名称和类型,它们确实是大写的。

I think you main problem is the definition of you types. 我认为你的主要问题是你的类型的定义。

You have to check which type is used in which line. 您必须检查在哪一行中使用的类型。

What you should have: 你应该拥有什么:

user1 -> NO TYPES, a package which calls user2-stuff user1 - > NO TYPES,一个调用user2-stuff的包

user2 -> Type1, Pack1, Proc1 user2 - > Type1,Pack1,Proc1

Example: 例:

-- 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;

Please remember: Two types are never the same! 请记住:两种类型永远不会相同! If you use a type in a schema, you're not allowed to define a similar-type in another schema, to retrieve the object. 如果在模式中使用类型,则不允许在另一个模式中定义类似类型以检索该对象。 You have to explicitly name the type in the other schema (=user2.type1). 您必须在另一个模式(= user2.type1)中明确命名该类型。 You have to grant rights to the schema/user which wants to use the type (in you example grant type- and package-privs). 您必须向想要使用该类型的模式/用户授予权限(在您的示例中为grant type-和package-privs)。

As troubleshooting in an existing project, you could check it step-by-step: 作为现有项目中的故障排除,您可以逐步检查:

  1. Logon with user1 使用user1登录
  2. Write some plsql which uses your type 写一些使用你的类型的plsql

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM