Oracle Database 21c Express Edition Release 21.0.0.0.0 - Production
Schematu HR.
If we want some flexibility in our system, there's nothing like dynamic SQL!
But sometimes dynamic SQL refuses to cooperate. Even though we have all the necessary permissions granted, we receive an error:
ORA-01031: insufficient privileges
Let's check what could be the cause of this and how we can solve the problem of lack of permissions.
We want to prepare a script that will dynamically create the table tab_dyn.
declare vsql varchar2(32000); begin vsql := 'create table tab_dyn (id number)'; DBMS_OUTPUT.put_line(vsql); execute immediate vsql; exception when others then DBMS_OUTPUT.put_line(sqlerrm); end; /
select * from tab_dyn; no rows selected
Tested, everything is working. So, we can save our anonymous block as a procedure:
drop table tab_dyn; create or replace procedure proc_dyn is vsql varchar2(32000); begin vsql := 'create table tab_dyn (id number)'; DBMS_OUTPUT.put_line(vsql); execute immediate vsql; exception when others then DBMS_OUTPUT.put_line(sqlerrm); end; /
We run the procedrue:
exec proc_dyn;
and..,?
create table tab_dyn (id number) ORA-01031: insufficient privileges PL/SQL procedure successfully completed.
Insufficient permissions? But how's that possible? It was working just a moment ago :o
The issue lies in the fact that if we want to use dynamic SQL, permissions for objects must be granted directly, not through a role. In this case, we need to grant the HR user the CREATE ANY TABLE privilege.
-- sys grant create any table to hr;
Let's do that again:
exec proc_dyn; select * from tab_dyn; no_rows_selected
This time it works.
Another solution is to create the procedure with AUTHID CURRENT_USER privileges.
We'll remove the permissions and drop the table:
revoke create any table from hr;
drop table tab_dyn;
Let's create the procedure proc_dyn again:
create or replace procedure proc_dyn AUTHID CURRENT_USER is vsql varchar2(32000); begin vsql := 'create table tab_dyn (id number)'; DBMS_OUTPUT.put_line(vsql); execute immediate vsql; exception when others then DBMS_OUTPUT.put_line(sqlerrm); end; /
Let's test it:
exec proc_dyn; select * from tab_dyn; no_rows_selected
It works!!!:)
Komentarze
Prześlij komentarz