Условие в сценарии SQL

У меня есть 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?


person Peter Lang    schedule 23.03.2010    source источник


Ответы (3)


Ваш вопрос и один из комментариев указывают на то, что вы хотите избежать блоков PL/SQL и НЕМЕДЛЕННО ВЫПОЛНИТЬ. Я также предполагаю, что под «реагированием на другие исключения» вы подразумеваете прекращение выполнения сценария при обнаружении исключения.

Если это так, я думаю, что лучшее, что вы можете сделать в чистом 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
person dpbradley    schedule 23.03.2010
comment
Спасибо! Это тоже сработает. Поскольку это никогда не подведет (даже если я напишу неверный код), я думаю, что буду придерживаться своего решения. - person Peter Lang; 07.04.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;
person Vincent Malgrat    schedule 23.03.2010
comment
@ Винсент Мальграт: Верно, но это все равно будет включать PL / SQL и EXECUTE IMMEDIATE ... - person Peter Lang; 23.03.2010
comment
@Peter: Да, я не думаю, что вы можете смоделировать алгоритм ветвления, используя только SQL * Plus. - person Vincent Malgrat; 23.03.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 за запрос словаря данных.

person Dana    schedule 14.04.2010