Эквивалентен SQLERRM, когда нет ошибок?

Кто-нибудь знает, есть ли эквивалент SQLERRM когда не произошло ошибок?

Я знаю, что могу подсчитать затронутые строки, как здесь, но могу ли я автоматически получить сообщение, которое я получу от SQLPLUS например role granted. после execute immediate в PL/SQL?

Я пытаюсь сделать

begin
  execute immediate 'grant select on s1.tbl1 to user1';
  dbms_output.put_line(<some function>);
end;

и получить

Grant succeeded.

Спасибо дж

2 ответа

Обратная связь типа "Грант удался". это особенность sqlplus.

Если вы включаете трассировку SQL*Net (подробнее http://docs.oracle.com/cd/E11882_01/java.112/e16548/apxtblsh.htm или http://www.juliandyke.com/Diagnostics/Trace/NetTrace.php) вы увидите, что строка "Предоставление выполнено успешно" НЕ является чем-то, что клиентское приложение sqlplus получает от Oracle.

Так как он знает, что отображать? Потому что sqlplus имеет механизм проверки типа команды перед отправкой на сервер. Если вы введете команду non-existend, то она даже не будет отправлена ​​на сервер (вы можете проверить это также в трассировке SQL*NET).

Кроме того, вы можете проверить список команд, если вы открываете бинарный файл sqlplus в виде текста и ищете, например, строку "grant" (нижний левый угол на скриншоте).

В приведенном ниже случае не будет обмена с сервером, потому что команда намеренно неверна.

SQL> some_command

SP2-0734: неизвестная команда начала "some_comma..." - остаток строки игнорируется.

Таким образом, Oracle знает тип команды перед отправкой текста SQL на сервер и для некоторых команд получает дополнительную информацию после выполнения. Как и количество строк, затронутых для DML. Этой информации достаточно для отображения "обратной связи".

Возвращаясь к вашей задаче, проще всего было бы реализовать примитивный разбор первых 1-3 слов команды и отобразить соответствующее сообщение, если ошибок не было.

Хардкорная опция - включить трассировку SQL и получить тип команды из файла трассировки.

=====================
PARSING IN CURSOR #3 len=31 dep=0 uid=91 oct=17 lid=91 tim=2178486867995 hv=3483936374 ad='b967c6a4' sqlid='10y8y7m7uj9mq'
grant execute on <...> to <...>
END OF STMT
PARSE #3:c=0,e=614,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,plh=0,tim=2178486867994
=====================

oct означает тип команды Oracle

SQL> select command_name from v$sqlcommand where command_type = 17;

COMMAND_NAME
----------------------------------------------------------------
GRANT OBJECT

Другой вариант - включить аудит, но я бы предпочел, чтобы он был простым.

Если это только вывод сообщения об успехе, это то, что нас интересует, тогда простое использование исключений поможет.

SET SERVEROUTPUT ON
BEGIN
  execute immediate 'grant select on s1.tbl1 to user1' ;
  dbms_output.put_line('Grant succeeded');
EXCEPTION
  WHEN OTHERS THEN
    dbms_output.put_line('Grant Failed');
    procedure_to_log_error(SQLERRM);
END;
Другие вопросы по тегам