Oracle 19c并行执行时角色授包权限无效,需直接授权用户
ORA-06550/PLS-00201 When Calling Parallelized Package Procedure via Role Grant
Problem Scenario
I've run into a permission issue with Oracle's DBMS_PARALLEL_EXECUTE when using role-based grants. Here's the setup:
- Two existing users:
ETLandDQ - Created a package
test_pkgin theDQschema withAUTHID CURRENT_USER; the package'stest_procusesDBMS_PARALLEL_EXECUTEto run parallel tasks that calltest_proc2 - Created a role
etl_process, granted it toETL, and grantedEXECUTEonDQ.test_pkgtoetl_process - When
ETLcallstest_proc, the parallel task throws:ORA-06550: PLS-00201: identifier 'DQ.TEST_PKG' must be declared - However, the operation works fine if I grant
EXECUTEonDQ.test_pkgdirectly toETL, or if I remove the parallel execution logic entirely.
Relevant Code
Package Specification (DQ schema):
create or replace package test_pkg authid current_user as procedure test_proc2(in_start number, in_end number); procedure test_proc; end test_pkg; /
Package Body (DQ schema):
create or replace package body test_pkg as procedure test_proc2 (in_start number, in_end number) as v_id number; begin select 1 into v_id from dual ; end test_proc2; procedure test_proc as begin begin dbms_parallel_execute.drop_task('test_task'); exception when others then null; end; dbms_parallel_execute.create_task ( task_name=>'test_task' ); dbms_parallel_execute.create_chunks_by_sql ( task_name => 'test_task', sql_stmt=> 'select 1 as start_id, 1 as end_id from dual', by_rowid => false ); dbms_parallel_execute.run_task ( task_name => 'test_task', sql_stmt => 'BEGIN dq.test_pkg.test_proc2 (in_start=>:start_id, in_end=>:end_id); END;', language_flag => DBMS_SQL.NATIVE, parallel_level => 1 ); end; end; /
Authorization Statements:
create role etl_process; grant etl_process to etl; grant execute on dq.test_pkg to etl_process;
Root Cause
The key issue here is how Oracle handles permissions in parallel execution sessions:
- When
DBMS_PARALLEL_EXECUTEruns tasks in parallel, it spawns independent background sessions to execute the dynamic SQL. - By default, Oracle does not enable roles in these non-interactive background sessions. Only permissions that are directly granted to the user (not via roles) are available in these sessions.
- Even though your package uses
AUTHID CURRENT_USER(which makes the package run with the caller's permissions), the dynamic SQL inrun_taskis executed in a separate session where theetl_processrole isn't active. This means the session can't resolveDQ.TEST_PKGbecause it doesn't have the necessary execute permission via the role.
Solutions
You have a few options to fix this:
- Directly grant permissions to the user: As you've already verified, granting
EXECUTEonDQ.test_pkgdirectly toETLwill work, because direct user grants are available in all sessions, including parallel background sessions.grant execute on dq.test_pkg to etl; - Use
AUTHID DEFINERfor the package: If security requirements allow, changing the package to useAUTHID DEFINERwill make it run with theDQuser's permissions. The parallel sessions will inheritDQ's rights, so they can accessDQ.test_pkgwithout additional grants. Note that this shifts the permission context to the package owner, so you need to ensure this aligns with your security model. - Explicitly enable the role in the dynamic SQL: While not ideal, you could add a statement to enable the
etl_processrole in the dynamic SQL block. However, this requires the user to have theSET ROLEprivilege, and it's generally less secure than the first two options.sql_stmt => 'BEGIN SET ROLE etl_process; dq.test_pkg.test_proc2 (in_start=>:start_id, in_end=>:end_id); END;'
内容的提问来源于stack exchange,提问作者HelOs




