I was asked if needs to grant direct access to other schema table inside a PL/SQL stored procedure/function. so I test it , which shows that role is deactivated, hence inside PL/SQL explicitly grant is needed.
1. The PL/SQL Function
CREATE OR REPLACE FUNCTION COPY_T1
(pKongNr IN NUMBER)
RETURN NUMBER
AUTHID CURRENT_USER
IS
BEGIN
INSERT INTO LIQY.T1
SELECT *
FROM OWNER1.T1
WHERE f1 = pKongNr;
return 0;
END;
2. Create the test table OWNER1.T1
ORACLE1@CUST1> conn OWNER1
Connected.
OWNER1@CUST1> create table t1 (f1 number);
Table created.
OWNER1@CUST1> insert into t1 values(1);
1 row created.
OWNER1@CUST1> commit;
Commit complete.
3. Create application id LIQY , liqy_role to access OWNER1.T1 table
OWNER1@CUST1> conn / as sysdba
Connected.
SYS@CUST1> create role liqy_role;
Role created.
SYS@CUST1> grant select on OWNER1.t1 to liqy_role;
Grant succeeded.
SYS@CUST1> grant liqy_role to liqy;
Grant succeeded.
SYS@CUST1> conn liqy
Connected.
LIQY@CUST1> create table liqy.t1 (f1 number);
Table created.
LIQY@CUST1> select * from liqy.t1;
no rows selected
LIQY@CUST1> select * from OWNER1.t1;
F1
----------
1
LIQY@CUST1> set role none;
Role set.
LIQY@CUST1> select * from OWNER1.t1;
select * from OWNER1.t1
*
ERROR at line 1:
ORA-00942: table or view does not exist
LIQY@CUST1> conn liqy
Enter password:
Connected.
LIQY@CUST1> select * from OWNER1.t1;
F1
----------
1
LIQY@CUST1> conn OWNER1
Enter password:
Connected.
OWNER1@CUST1> insert into t1 values (2);
1 row created.
OWNER1@CUST1> insert into t1 values (3);
1 row created.
OWNER1@CUST1> insert into t1 values (4);
1 row created.
OWNER1@CUST1> insert into t1 values (5);
1 row created.
OWNER1@CUST1> conn liqy
Enter password:
Connected.
LIQY@CUST1> select * from OWNER1.t1;
F1
----------
1
2
3
4
5
5. Compile the function
LIQY@CUST1> CREATE OR REPLACE FUNCTION COPY_T1
2 (pKongNr IN NUMBER)
3 RETURN NUMBER
4 AUTHID CURRENT_USER
5 IS
6 BEGIN
7 INSERT INTO LIQY.T1
8 SELECT *
9 FROM OWNER1.T1
10 WHERE f1 = pKongNr;
11 END;
12 /
Warning: Function created with compilation errors.
LIQY@CUST1> SHOW ERRORS
Errors for FUNCTION COPY_T1:
LINE/COL ERROR
-------- -----------------------------------------------------------------
7/4 PL/SQL: SQL Statement ignored
9/19 PL/SQL: ORA-00942: table or view does not exist
6. grant explicitly to fix the error
SYS@CUST1> conn OWNER1
Enter password:
Connected.
OWNER1@CUST1> grant select on t1 to liqy;
Grant succeeded.
OWNER1@CUST1> conn liqy
Enter password:
Connected.
LIQY@CUST1> CREATE OR REPLACE FUNCTION COPY_T1
2 (pKongNr IN NUMBER)
3 RETURN NUMBER
4 AUTHID CURRENT_USER
5 IS
6 BEGIN
7 INSERT INTO LIQY.T1
8 SELECT *
9 FROM OWNER1.T1
10 WHERE f1 = pKongNr;
11 END;
12 /
Function created.
7. But hit new error, so I googled and learned .
LIQY@CUST1> select copy_t1(2) from dual;
select copy_t1(2) from dual
*
ERROR at line 1:
ORA-14551: cannot perform a DML operation inside a query
ORA-06512: at "LIQY.COPY_T1", line 7
LIQY@CUST1> exec copy_t1(2);
BEGIN copy_t1(2); END;
*
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00221: 'COPY_T1' is not a procedure or is undefined
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
LIQY@CUST1> var r number
LIQY@CUST1> select copy_t1(2) into :r from dual;
select copy_t1(2) into :r from dual
*
ERROR at line 1:
ORA-14551: cannot perform a DML operation inside a query
ORA-06512: at "LIQY.COPY_T1", line 7
LIQY@CUST1> call copy_t1(2) into :r ;
call copy_t1(2) into :r
*
ERROR at line 1:
ORA-06503: PL/SQL: Function returned without value
ORA-06512: at "LIQY.COPY_T1", line 11
LIQY@CUST1> select * from liqy.t1;
no rows selected
LIQY@CUST1> CREATE OR REPLACE FUNCTION COPY_T1
2 (pKongNr IN NUMBER)
3 RETURN NUMBER
4 AUTHID CURRENT_USER
5 IS
6 BEGIN
7 INSERT INTO LIQY.T1
8 SELECT *
9 FROM OWNER1.T1
10 WHERE f1 = pKongNr;
11 return 0;
12 END;
13 /
Function created.
LIQY@CUST1> call copy_t1(2) into :r ;
Call completed.
LIQY@CUST1> select * from liqy.t1;
F1
----------
2
LIQY@CUST1> call copy_t1(5) into :r ;
Call completed.
LIQY@CUST1> call copy_t1(6) into :r ;
Call completed.
LIQY@CUST1> select * from liqy.t1;
F1
----------
2
5
References:
Accessing another user's table within an Oracle Stored Procedure
Why do I get a "ORA-01031: insufficient privileges" or "PLS-00201: identifier'x' must be declared" in my stored procedures?
ORA-14551: cannot perform a DML operation inside a query tips |