此问题已在此处有答案:
Execute Immediate fails even with CREATE table grant(4个答案)
Getting Insufficient Privilege while creating Oracle sequence using procedure but not using plsql block(2个答案)
Why doesn't PL/SQL respect privileges granted by Roles?(5个答案)
昨天关门了。
从匿名PL/SQL块运行CREATE PROCEDURE语句的EXECUTE IMMEDIATE正在按预期工作。但是,如果我在一个独立的过程中有相同的查询,并从PL/SQL块调用该过程,它会给出以下错误:ORA-01031: insufficient privilege
示例:
connect sys/<sys_pass>@<tns_alias> as sysdba;
alter session set "_oracle_script"=true;
-- not relevant, just for dropping the user
-- https://stackoverflow.com/a/50711859/10721332
CREATE OR REPLACE PROCEDURE drop_user
( user_name IN varchar2 )
IS
v_user_exists NUMBER;
BEGIN
LOOP
FOR c IN (SELECT s.sid, s.serial# FROM v$session s WHERE upper(s.username) = user_name)
LOOP
EXECUTE IMMEDIATE
'alter system kill session ''' || c.sid || ',' || c.serial# || ''' IMMEDIATE';
END LOOP;
BEGIN
EXECUTE IMMEDIATE 'drop user ' || user_name || ' cascade';
EXCEPTION WHEN OTHERS THEN
IF (SQLCODE = -1940) THEN
NULL;
ELSE
RAISE;
END IF;
END;
BEGIN
SELECT COUNT(*) INTO v_user_exists FROM dba_users WHERE username = user_name;
EXIT WHEN v_user_exists = 0;
END;
END LOOP;
END;
/
call drop_user('CREED');
create user creed identified by bratton;
grant connect, resource to creed;
grant unlimited tablespace to creed;
connect creed/bratton@<tns_alias>;
set serveroutput on;
---------------------------------------------------
CREATE OR REPLACE PROCEDURE executor(
query VARCHAR2
) IS
BEGIN
EXECUTE IMMEDIATE query;
EXCEPTION
WHEN OTHERS THEN dbms_output.put_line(sqlerrm || ' : ' || query);
END;
/
DECLARE
query1 varchar2(200);
query2 varchar2(200);
BEGIN
query1 := 'create or replace procedure PROC1 is begin dbms_output.put_line(''hello world''); end;';
executor(query1); -- doesn't work
query2 := 'create or replace procedure PROC2 is begin dbms_output.put_line(''hello world''); end;';
EXECUTE IMMEDIATE query2; -- works
END;
/
为什么query 2能正常工作,而query 1却不能执行?
我尝试了以下方法,但还是出现了同样的错误:
1.更改过程中的CURRENT_SCHEMA
1.在过程名称中添加SCHEMA前缀
1条答案
按热度按时间juzqafwq1#
您似乎是通过role获得权限的;如果是这样,那么它就像预期的那样工作,因为这样的特权将在SQL级别或匿名PL/SQL块上工作,但不会在命名过程(即存储过程,函数,包,触发器)中工作。
怎么办?直接**授予权限,而不是通过角色。