2009-10-13 5 views
0

В наших Хранимых процедурах у нас есть следующий код в самом конце.<<SQL_ERROR>> блок

<<SQL_ERROR>> 
    V_SYS_ERROR_MSG := SUBSTR(SQLERRM, 1, 252); 

    DBMS_OUTPUT.PUT_LINE('ERROR IN EXECUTION IN PROCEDURE'); 

    DBMS_OUTPUT.PUT_LINE('THE ERROR CODE IS ' || V_SYS_ERROR || '- ' || 
         V_SYS_ERROR_MSG); 

У нас есть заявления вроде следующего, которые вызывают блок ошибок.

IF V_SYS_ERROR <> 0 THEN 
    GOTO SQL_ERROR; 

Операторы вывода СУБД поступают даже в случае отсутствия ошибки. Как мы можем избежать этого?

ответ

2

Я не рекомендовать этот GOTO подход: как и другие уже говорил, исключения является правильным способом обработки ошибок в PL/SQL. Но для решения вашего конкретного вопроса, то вы можете сделать это:

BEGIN 
    IF V_SYS_ERROR <> 0 THEN 
    GOTO SQL_ERROR; 
    END IF; 

    GOTO PROC_END; 

    <<SQL_ERROR>> 
    V_SYS_ERROR_MSG := SUBSTR(SQLERRM, 1, 252); 

    DBMS_OUTPUT.PUT_LINE('ERROR IN EXECUTION IN PROCEDURE'); 

    DBMS_OUTPUT.PUT_LINE('THE ERROR CODE IS ' || V_SYS_ERROR || '- ' || 
         V_SYS_ERROR_MSG); 

    <<PROC_END>> 
    NULL; 
END; 

Конечно, это по-прежнему включает в себя изменение кода, так что если вы делаете, что почему бы не сделать это правильно так или иначе? т.е.

DECLARE 
    SQL_ERROR EXCEPTION; 
BEGIN 
    IF V_SYS_ERROR <> 0 THEN 
    RAISE SQL_ERROR; 
    END IF; 

EXCEPTION 

    WHEN SQL_ERROR THEN 
    V_SYS_ERROR_MSG := SUBSTR(SQLERRM, 1, 252); 

    DBMS_OUTPUT.PUT_LINE('ERROR IN EXECUTION IN PROCEDURE'); 

    DBMS_OUTPUT.PUT_LINE('THE ERROR CODE IS ' || V_SYS_ERROR || '- ' || 
         V_SYS_ERROR_MSG); 
    RAISE; 

END; 

Кстати, DBMS_OUTPUT.PUT_LINE не подходит для вывода сообщений об ошибках в системе производства приложений. Используйте его только для отладки во время разработки.

2

вы должны избегать заявлений GOTO, они грязные, как вы заметили. PL/SQL поставляется с обработкой ошибок, вы должны использовать EXCEPTION synthax, чтобы иметь дело с ошибками:

BEGIN 
    <code goes here> 
EXCEPTION 
    WHEN <exception> THEN 
     <deal_with_it> 
    WHEN OTHERS THEN 
     <log_error> 
     RAISE; 
END; 
+0

Как вы упомянули, нам придется обрабатывать исключения, когда они происходят правильно? Однако это не очень хорошо для нас. мы конвертируем множество хранимых процедур сервера sql в oracle, а инструмент, который мы использовали (разработчик sql), сделал инструкции goto. мы не хотели бы входить в каждый SP и начинать возиться с логикой – Omnipresent

+0

@Omnipresent: Когда вы говорите «разработчик SQL», вы имеете в виду Oracle SQL Developer или какой-либо другой инструмент с тем же именем? –

+0

Oracle sql Developer – Omnipresent

1

Я не думаю, что вы получите результаты, которые вы хотите без использования обработчика исключений. Из руководства пользователя PL/SQL:

SQLERRM без аргумента полезен только в обработчике исключений. Вне обработчик, SQLERRM без аргумента всегда возвращает нормальное, успешное сообщение о завершении .

В первую очередь, возможно, что произошла ошибка, но вы видите сообщение «нормальное успешное завершение», потому что это то, что SQLERRM всегда будет возвращать в этом контексте.

Предполагая, что это не так, похоже, что вы просто позволяете управлять потоком из «нормального» кода в «обработчик ошибок». Если обработчик ошибок находится в самом конце процедуры, то простым решением было бы добавить оператор RETURN непосредственно перед меткой <>.

Лучшим решением было бы переместить код обработчика ошибок в отдельную процедуру и вызвать эту процедуру вместо использования GOTO.

Смежные вопросы