Bypass "table or view does not exist" in package compilation - oracle

There are two schemas in a Oracle database.
MYSCHEMA that is controlled by me.
OTHERSCHEMA that is not controlled by me.
I just know I can get result from select * from OTHERSCHEMA.OTHEROBJECT. However, OTHEROBJECT is a synonym.
In my package, I have a statement like
insert into MYSCHEMA.MYTABLE(COL1) select COL1 from OTHERSCHEMA.OTHEROBJECT;
But it gave me Table or view does not exist.
How can I solve or bypass this problem? Thanks!

I assume you received the privilege to select from otherschema.otherobject by means of a role as opposted to a direct grant (such as grant all on otherschema.otherobject to myschema). If this is the case, the privileges within this role will not be used to determine what rights you have within a PL/SQL block.
See also How Roles Work in PL/SQL Blocks (Oracle Docu, where it says under Roles Used in Named Blocks with Definer's Rights:
All roles are disabled in any named PL/SQL block (stored procedure, function, or trigger) that executes with definer's rights. Roles are not used for privilege checking and you cannot set roles within a definer's rights procedure.)

Related

Create stored procedure in Oracle with Roles privileges

I have a problem with creating a stored procedure.
I have permissions to the table XYZ through Roles, so when I do a SELECT to the table XYZ I don't have problem, but when I want to create a stored procedure (inside my code I call to the table XYZ table) Oracle tell me:
Table or view doesn't exist.
When another user who have directly permissions for table XYZ create the stored procedure with the same code don't have problems.
So I hope you could help me. I think I need to assign another kind of permission to the Role that I use.
From the documentation:
How Roles Work in PL/SQL Blocks
Role behavior in a PL/SQL block is determined by the type of block and
by definer's rights or invoker's rights.
Roles Used in Named Blocks with Definer's Rights
All roles are disabled in any named PL/SQL block that executes with
definer's rights.
Roles Used in Named Blocks with Invoker's Rights and Anonymous PL/SQL
Blocks
Named PL/SQL blocks that execute with invoker's rights and anonymous
PL/SQL blocks are executed based on privileges granted through enabled
roles.
Roles Used in Named Blocks with Definer's Rights
All roles are disabled in any named PL/SQL block that executes with
definer's rights.
Examples of named PL/SQL blocks are stored procedures, functions, and
triggers.
Roles are not used for privilege checking and you cannot set roles
within a definer's rights procedure.
This is from the 19c documentation, but it has been true pretty much forever.
You only have 2 solutions:
either your Oracle user is granted the direct privilege on the table (ie without a role)
or you create a stored procedure with invoker rights.
Here is an example of invoker right procedure.
Use AUTHID CURRENT_USER clause and access table SCHEMA.XYZ with dynamic SQL because invoker rights are not enabled at PL/SQL compilation time but only at PL/SQL run time.
create or replace procedure myproc
authid current_user
as
l number;
begin
execute immediate 'select c from schema.xyz where rownum = 1' into l;
dbms_output.put_line('l= ' || l);
end;
/

How to see my own actual Oracle SQL statement that is being executed as normal user

How to see my own actual Oracle SQL statement that is being executed as normal user not DBA?
Which grants are needed? v_$session? ...
Oracle v$ views are named V_$VIEWNAME and their synonyms are created as: V$VIEWNAME
You need to give the SELECT rights on it as follows:
SQL> grant select on v_$session to <your_user>;

Insert data in a table in another schema from a materialized view using a procedure in Oracle

I've been trying to insert data from a materialized view into a table that belongs to a different scheme using a procedure, but when I compile the procedure I get the error of: table or view doesn't exist. I have checked and I have selection and insertion privileges on that table. create or replace PROCEDURE PROCEDURE_MYPROCEDURE AS
BEGIN
INSERT INTO SCHEME.TABLE
(COLUMN1,COLUM2)
SELECT COLUMN1,COLUMN2
FROM MATERIALIZED_VIEW;
END PROCEDURE_MYPROCEDURE;
this line SCHEME.TABLEshows the message "PL/SQL: STATEMENT IGNORED", "TABLE OR VIEW DOES NOT EXIST"
The most likely cause is that you have access via a role not directly, which means you can run it in SQL but for a PLSQL procedure you need a direct privilege granted.
As per the Application Developer guide:
Privileges Required to Create Procedures and Functions
To create a stand-alone procedure or function, or package specification or
body, you must meet the following prerequisites:
You must have the CREATE PROCEDURE system privilege to create a
procedure or package in your schema, or the CREATE ANY
PROCEDURE system privilege to create a procedure or package in
another user’s schema.
Attention: To create without errors, that is, to compile the procedure
or package successfully, requires the following additional privileges:
The owner of the procedure or package must have been explicitly
granted the necessary object privileges for all objects referenced within
the body of the code; the owner cannot have obtained required
privileges through roles.
If the privileges of a procedure’s or package’s owner change, the procedure
must be reauthenticated before it is executed. If a necessary privilege to a
referenced object is revoked from the owner of the procedure (or package), the
procedure cannot be executed.
An easy way to test things is:
SQL> set role none;
SQL> "statement you want to test to see if it'll work in a procedure"
So you might just be missing some direct grants on those objects.
If the procedure is compiled on user a and the MATERIALIZED_VIEW is owned by user b. When you execute the procedure it will look for the materialized view on user a.
Put the user/schema in front of the MATERIALIZED_VIEW.
You would also need to grant select on MATERIALIZED_VIEW to user a.

Create stored procedure with table from another schema throws PLS-00201

Oracle 10g. I'm new to procedures, so maybe I'm missing something obvious.
Schema owner ABC has table T2001_WRITEOFF. First I had granted SIUD to some_update_role, and granted that role to developer user IJK. User IJK then created synonym T2001_WRITEOFF for ABC.T2001_WRITEOFF; This worked with normal SQL DML commands.
However, I read elsewhere on here that grants via a role do not work in stored procedures. I dropped the synonym from IJK; then from ABC, granted SIUD directly to IJK. From IJK, normal SQL DML works.
When I try to create a simple procedure as follows, it throws PLS-00201 identifier 'T2001_WRITEOFF' must be declared, and points to the 2nd line. This error is the same whether I use the role grants or not.
create or replace procedure woof1(
fooname in T2001_WRITEOFF.territory%TYPE, <=== error points here
bardesc IN T2001_WRITEOFF.ind_batch_submit%TYPE) IS
BEGIN
INSERT into T2001_WRITEOFF
VALUES ( fooname, bardesc);
END woof1;
/
Thanks in advance for help
JimR
In order to make role right applicable in stored procedures you might want to look at authid current_user in the oracle documentation. Also helpful: http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/subprograms.htm#LNPLS682

Oracle stored procedure DB Link question

I have a stored procedure FOO belonging to user A. User B has EXECUTE permission on FOO.
One of the procedures in FOO uses a DB Link to retrieve data from BARTABLE#REMOTEDB. A has a DB Link to REMOTEDB connecting as user AREMOTE while B has a DBLink with the same name connecting to REMOTEDB but as user BREMOTE.
When B executes FOO, will it use A's DB Link (connecting as AREMOTE) or B's DB Link (Connecting as BREMOTE)?
I ask because I assumed a procedure belonging to a particular user would only have access to that user's dblinks even if another user had EXECUTE on that procedure. But somehow this procedure is working properly even though the user AREMOTE does not have SELECT on BARTABLE#REMOTEDB, so I'm confused.
The procedure should use the dblink that is defined for A's link. Any oracle procedure uses the rights of the owner to process, except where that procedure has been defined with "Invoker's Rights". Invoker's Rights
Invoker's rights defined for a procedure tells the code to use the rights and objects local to the calling user, and not the code owner. The reason that this is not done by default is typically an end user will have no rights to any hard objects for direct update, but be given proper access through an API, which would apply the correct business logic to updates, inserts and deletes, and then these objects would be exposed as accessible to the end user.

Resources