views:

112

answers:

3

I've got an SQL-script executed by SQL*Plus, that needs to run with Oracle 10g and Oracle 11g.

That script gives grants on a package that does not exist before 11g:

GRANT EXECUTE ON sys.dbms_result_cache TO my_user;

I would like to avoid the exception on 10g, since I want to react to other exceptions in the script.


One way is to use Conditional Compilation and dbms_db_version:

BEGIN
  $IF dbms_db_version.ver_le_10 $THEN NULL; $ELSE
    EXECUTE IMMEDIATE 'GRANT EXECUTE ON sys.dbms_result_cache TO my_user';
  $END
END;
/

Is there any other way, preferable without using PL/SQL?

+1  A: 

Hi Peter,

you could check if the object exists beforehand:

BEGIN
   FOR cc IN (SELECT NULL
                FROM all_objects
               WHERE owner = 'SYS'
                 AND object_name = 'DBMS_RESULT_CACHE'
                 AND ROWNUM = 1) LOOP
      EXECUTE IMMEDIATE 'GRANT EXECUTE ON sys.dbms_result_cache TO my_user';
   END LOOP;
END;
Vincent Malgrat
@Vincent Malgrat: True, but it still would involve PL/SQL and `EXECUTE IMMEDIATE`...
Peter Lang
@Peter: Yes, I don't think you can simulate a branching algorithm using only SQL*Plus.
Vincent Malgrat
+2  A: 

Your question and one of the comments indicate that you want to avoid PL/SQL blocks and EXECUTE IMMEDIATE. I also assume that by "react to other exceptions" you mean abort execution of the script when an exception is encountered.

If so, I think the best you can do in pure SQL/SQL*Plus is to ignore the exception exit for the grant statement:

... first part of script (with exit on sqlerror in effect)
WHENEVER SQLERROR CONTINUE
GRANT EXECUTE ON sys.dbms_result_cache TO my_user;
WHENEVER SQLERROR EXIT SQL.SQLCODE
... remaining part of script
dpbradley
Thanks! This would work too. Since it would never fail though (even if I write invalid code) I guess I'm going to stick with my solution.
Peter Lang
A: 

You can simulate branching by writing SQL that generates SQL and spools it to a sql script. Then run the sql script:

define temp_file='somefile.sql'

set heading off
set feedback off
spool &&temp_file

SELECT 'GRANT EXECUTE ON sys.dbms_result_cache TO my_user;'
  FROM all_objects
 WHERE owner = 'SYS'
   AND object_name = 'DBMS_RESULT_CACHE';

spool off
@&&temp_file
host rm &&temp_file

Thanks to @Vincent for the data dictionary query.

Dana