4

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.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Lone_Wanderer
  • 179
  • 1
  • 3
  • 16
  • What is `Types` - another package that defines things including `type1`? Or is `type1` a SQL-level type? Which user owns the packages/types, and which one are you running this anonymous block as? – Alex Poole Jan 06 '17 at 10:42
  • 1
    Does the user have privileges directly or through a role (e.g. DBA role)? – Wernfried Domscheit Jan 06 '17 at 10:42
  • @AlexPoole Sorry for not clearing it up. 'type1' is a table of 'type2'. To make it more clear, here is the code: `create or replace TYPE type1 IS TABLE OF type2;` – Lone_Wanderer Jan 06 '17 at 10:52
  • It also helps to show the full error you get iin the question. The title says 'TYPE', but is it really reporting 'TYPE1', as your question says? Also edit the question to make it clear which user owns the package and type. When you look at them, including the grants, are you going into the 'other users' list in SQL Developer to see them? – Alex Poole Jan 06 '17 at 10:53
  • @AlexPoole While 'type2' is the table itself. – Lone_Wanderer Jan 06 '17 at 10:54
  • 1
    OK, so you are already qualifying the type with its owner; so are you sure your user has been granted privileges on that SYSADM-owned type? Both the table type, and the underlying type it is a table of? (As Wernfried said, it can matter whether hose are granted directly or via a role - but not if you're really using an anonymous block). Also the `create type` you showed doesn't match the type name in the error message? – Alex Poole Jan 06 '17 at 11:07
  • @AlexPoole Question edited. – Lone_Wanderer Jan 06 '17 at 12:11
  • An interesting fact is that I dont see anything from my perspective. I would expect that if I have the privileges, I would see refferenced procedurs, yet I still have to go browsing a different user to see them. – Lone_Wanderer Jan 06 '17 at 12:14
  • 1
    No, I'd expect that part. If you can see the types and packages under 'other users' that implies you have at least some privs. But you have to qualify calls; which you're now doing. And you aren't getting errors from the package, from what you showed. Unless you have the type name misspelled (or possibly it has a quoted identifier? hopefully not) I'm not sure. It might be something obvious and simple, that we can't see. Just clarify: you have execute privs on the table type and its underling type, as your user? – Alex Poole Jan 06 '17 at 12:32
  • @AlexPoole I do, at least I do have the rights I would expect to need. – Lone_Wanderer Jan 06 '17 at 12:55
  • 3
    The query against `USER_TAB_PRIVS`showed identifiers: user1 user2 type1 type2 etc - **all in lower case**. This means that they probably have been created using **quoted identifiers**, and you must use **quoted identifiers** to reference them, eg `"user1"."type1"`. If you use **nonquoted identifiers**, for example: `user1.type1`' - then Oracle store them and treats them as uppercase. See this for details: https://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements008.htm – krokodilko Jan 06 '17 at 13:18
  • @krokodilko My bad, when I was rewriting the the table, i forgot to use uppercase. I'm sorry for that. I realize that I'm making it more difficult for you by not showing real names but i really need to be carefull what I post here. – Lone_Wanderer Jan 06 '17 at 13:32
  • @Lone_Wanderer what do you get when you run: `SELECT owner, object_name, status FROM all_objects WHERE object_type = 'TYPE' AND object_name IN ('TYPE1', 'TYPE2');` as both users? (if you don't see anything, try querying `dba_objects` instead) – Boneist Jan 06 '17 at 15:04
  • @Boneist I get the owner of the Types (user2), and the fact that they are valid. – Lone_Wanderer Jan 06 '17 at 16:17
  • 1
    @Lone_Wanderer and it's the same when you run the query as both users? (all_objects will return the object if the user has the necessary privs) – Boneist Jan 06 '17 at 16:18

1 Answers1

1

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

kara
  • 3,205
  • 4
  • 20
  • 34