Question

I have a problem. SET ROLE does not work as I expected. I have code sample:

DECLARE 
  ln_ln NUMBER;
  ln_1 NUMBER;
BEGIN
  ln_ln := DBMS_SQL.OPEN_CURSOR;
  DBMS_SQL.PARSE(ln_ln, 'SET ROLE SOME_ROLE IDENTIFIED BY SOME_PASSWORD',DBMS_SQL.NATIVE);
  ln_1 := DBMS_SQL.EXECUTE(ln_ln);
  DBMS_SQL.CLOSE_CURSOR(ln_ln);
  ln_ln := SOME_PACKAGE.SOME_FUNCTION;
END;

The SOME_ROLE have grant to SOME_PACKAGE. When I run this block, I get error that package does not exists. When I run this everything is fine:

DECLARE
  ln_ln NUMBER;
  ln_1 NUMBER;
BEGIN
  ln_ln := DBMS_SQL.OPEN_CURSOR;
  DBMS_SQL.PARSE(ln_ln, 'SET ROLE SOME_ROLE IDENTIFIED BY SOME_PASSWORD',DBMS_SQL.NATIVE);
  ln_1 := DBMS_SQL.EXECUTE(ln_ln);
  DBMS_SQL.CLOSE_CURSOR(ln_ln);
END;
/
DECLARE
  ln_ln NUMBER;
BEGIN
  ln_ln := SOME_PACKAGE.SOME_FUNCTION;
END;

When I run this, everything is good too:

DECLARE
  ln_ln NUMBER;
BEGIN
  ln_ln := DBMS_SQL.OPEN_CURSOR;
  DBMS_SQL.PARSE(ln_ln, 'SET ROLE SOME_ROLE IDENTIFIED BY SOME_PASSWORD',DBMS_SQL.NATIVE);
  ln_1 := DBMS_SQL.EXECUTE(ln_ln);
  DBMS_SQL.CLOSE_CURSOR(ln_ln);
  EXECUTE IMMEDIATE 'BEGIN :x := SOME_PACKAGE.SOME_FUNCTION; END;' USING OUT ln_ln;
END;

I tried EXECUTE IMMDIATE, DBMS_SESSION.SET_ROLE and DBMS_UTILITY.exec_ddl_statement instead of DBMS_SQL.EXECUTE. Can anyone tell me some workaround or explain why this stuff keeps happening.

Was it helpful?

Solution

As I undertand you have no permissions to access SOME_PACKAGE before you run SET ROLE . In this case, your first script will never work, because pl/sql is not a scripting language, it compiles code before running it. When parser reaches SOME_PACKAGE it fails because your user doesn't know what that string is.

You already have a solutions:

  1. make 2 anonimous blocks

    • grant permissions
    • execute function (this block is compiled only after first block is executed)
  2. use dynamic sql like EXECUTE IMMEDIATE (code comiled at runtime)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top