Условие в сценарии SQL - PullRequest
4 голосов
/ 23 марта 2010

У меня есть SQL-скрипт, выполняемый SQL * Plus, который должен работать с Oracle 10g и Oracle 11g .

Этот скрипт предоставляет гранты на пакет, который не существует до 11g:

GRANT EXECUTE ON sys.dbms_result_cache TO my_user;

Я бы хотел избежать исключения для 10g, поскольку я хочу реагировать на другие исключения в сценарии.


Один из способов - использовать Условная компиляция и 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;
/

Есть ли другой способ, предпочтительный без использования PL / SQL?

Ответы [ 3 ]

2 голосов
/ 23 марта 2010

Ваш вопрос и один из комментариев указывают на то, что вы хотите избежать блоков PL / SQL и выполнить EXECUTE IMMEDIATE. Я также предполагаю, что под «реагировать на другие исключения» вы подразумеваете прерывание выполнения скрипта при возникновении исключения.

Если это так, я думаю, что лучшее, что вы можете сделать в чистом SQL / SQL * Plus, - это игнорировать исключительную ситуацию для оператора предоставления:

... 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
1 голос
/ 14 апреля 2010

Вы можете смоделировать ветвление, написав SQL, который генерирует SQL и помещает его в сценарий sql. Затем запустите сценарий sql:

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

Спасибо @Vincent за запрос к словарю данных.

1 голос
/ 23 марта 2010

вы можете проверить, существует ли объект заранее:

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;
...