Lone_Wanderer
Lone_Wanderer

Reputation: 189

PLS-00201: identifier 'TYPE' must be declared

I'm connecting to an Oracle database as user1. Within the database, user2 exists and has a package pack1 which contains two stored procedures, proc1 and proc2.

I'm trying to call those procedures, but I'm getting the aforementioned error. The error mentions 'type1' that is defined in Types.

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.

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. Interestingly, when I run my code, mentioned error is thrown. When I run the "default" code I get "Relative path in absolute URI" error.

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:

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.
To further explain what 'type1' is, it is a refference to a table ('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:

DECLARE
ClientData user2.type1;

however, it reproduced the same error:

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

EDIT 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. 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.
Also, I am positive that I have privileges (EXECUTE & DEBUG) to all required objects. 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
EDIT 4
This is the outcome of 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. As suggested however, I double-checked the names of the package and the Types, they are indeed in upper case.

Upvotes: 4

Views: 9623

Answers (1)

kara
kara

Reputation: 3455

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

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). You have to grant rights to the schema/user which wants to use the type (in you example grant type- and package-privs).

As troubleshooting in an existing project, you could check it step-by-step:

  1. Logon with user1
  2. Write some plsql which uses your type

    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

Upvotes: 1

Related Questions