2013-02-26 5 views
2

У меня есть хранимая процедура, которая, кажется, неправильно регистрирует ее ошибки.Попробуйте и поймать на TSQL - не поймать

Код является ошибкой, но блок catch, похоже, не вступает в силу.

Блок try довольно длинный, но раздел с ошибкой прост и подходит к концу, поэтому я сделал это.

BEGIN TRY 
insert into tbl_X 
select * from #temp_tbl_Y 

RETURN 1 
END TRY 

BEGIN CATCH 
    Insert Into ExtractsErrorLog 
    SELECT 
    getdate() as ErrorDate 
    ,object_name(@@procid) as ProcedureName 
    ,ERROR_NUMBER() as ErrorNumber 
    ,ERROR_LINE() as ErrorLine 
    ,ERROR_MESSAGE() as ErrorMessage 
    ; 
DECLARE @errormessage as varchar(max); 
DECLARE @errorseverity as int; 
DECLARE @errorstate as int; 

set @errormessage = ERROR_MESSAGE(); 
set @errorseverity = ERROR_SEVERITY(); 
set @errorstate = ERROR_STATE(); 

RAISERROR (@errormessage, 
      @errorseverity, 
      @errorstate 
       ); 


END CATCH; 

Ошибка процедурный объект не удается на наш старый друг «Имя столбца или количество предоставленных значений не соответствует определению таблицы.» Я исправил эту ошибку - это была глупая ленивая ошибка, но я сбив с толку, почему мой процесс регистрации ошибок не работал, ни одна строка не вставлена ​​в мою таблицу ExtractsErrorLog.

+2

Это ошибка времени компиляции, увидеть это: http://stackoverflow.com/questions/7286667/sql-try-catch-statement-not-handling-error- sql-server-2008 –

+0

Можете ли вы опубликовать определение таблицы 'ExtractsErrorLog'? – Lamak

+0

Спасибо, Иван - это имеет большой смысл - и эта нить также предлагает обходное решение. Извините, что пропустили его и отправили обратно. Я бы прочитал, что catch не поймал компиляцию, но я не вел, что это будет ошибка компиляции. Кто-нибудь знает, есть ли руководство в Интернете, чтобы понять, какие ошибки возникают при компиляции/перекомпиляции. Я могу понять, почему это было бы сейчас, и я полагаю, что отсутствующие таблицы и т. Д. Тоже? Но я хотел бы быть уверенным, и я не очень много думал об этом. – DanBennett

ответ

6

TSQL TRY...CATCH не понимает эту ошибку. Эта ошибка относится к ошибкам типа «компиляция/перекомпиляция», которые не обрабатываются блоком CATCH «на одном уровне выполнения».

От MSDN:

следующие типы ошибок не обрабатываются с помощью CATCH блока, когда они происходят на том же уровне исполнения, как TRY ... CATCH конструкции:

  • Compile ошибки, такие как синтаксические ошибки, которые предотвращают запуск пакета из .

  • Ошибки, возникающие при заявлении на уровне перекомпиляции, такие как ошибки разрешения имен объектов, которые происходят после компиляции, поскольку резолюции отложено имя

...

You может использовать TRY ... CATCH для обработки ошибок, возникающих во время компиляции , или рекомпиляции на уровне инструкции путем выполнения генерирования ошибок в отдельной партии в блоке TRY. Например, вы делаете , помещая код в хранимую процедуру или выполняя динамический оператор Transact-SQL , используя sp_executesql. Это позволяет TRY ... CATCH уловить ошибку на более высоком уровне выполнения, чем ошибка ошибки . Например, следующий код показывает сохраненную процедуру , которая генерирует ошибку разрешения имен объектов. Пакет , содержащий конструкцию TRY ... CATCH, выполняется на более высоком уровне , чем хранимая процедура; и ошибка, которая возникает на более низком уровне , ломается.

я столкнулся с подобными проблемами с скриптом создания транзакции внутри TRY...CATCH что бы ROLLBACK сделку, если это не удалось.Заявление внутри транзакции бросало ту же ошибку и заставляло транзакцию никогда не закрываться, поскольку CATCH никогда не вводился.

Как упоминалось в статье MSDN, одним из вариантов является создание хранимой процедуры из вашего оператора INSERT, а затем вызов внутри вашей попытки/catch. Если sproc ошибочен, вы поймаете ошибку компиляции, пытаясь ее создать. Если впоследствии определение таблицы изменяет недействительность sproc, то TRY...CATCH поймает для вас исключение.

Если вы хотите, чтобы все было в одном скрипте, вы можете сделать это temporary stored procedure, но тогда вам нужно будет обрабатывать ошибки компиляции во время создания sprocs. Это не красиво, но это будет работать:

-- Creating error sproc to re-use code 
CREATE PROCEDURE #HandleError AS 
    Insert Into ExtractsErrorLog 
    SELECT GETDATE() as ErrorDate 
      ,object_name(@@procid) as ProcedureName 
      ,ERROR_NUMBER() as ErrorNumber 
      ,ERROR_LINE() as ErrorLine 
      ,ERROR_MESSAGE() as ErrorMessage; 

    DECLARE @errormessage as varchar(max); 
    DECLARE @errorseverity as int; 
    DECLARE @errorstate as int; 

    set @errormessage = ERROR_MESSAGE(); 
    set @errorseverity = ERROR_SEVERITY(); 
    set @errorstate = ERROR_STATE(); 

    RAISERROR (@errormessage, 
       @errorseverity, 
       @errorstate); 
GO 

-- Create a stored procedure of our INSERT and catch any compilation errors 
CREATE PROCEDURE #TEST AS 
    insert into tbl_X 
    select * from #temp_tbl_Y 
GO 
IF (@@ERROR <> 0) BEGIN 
    exeC#HandleError 
    -- If there was an error creating the sprocs, don't continue to the next batch 
    RETURN 
END 

-- If compilation succeeded, then run the sproc 
BEGIN TRY 
    exeC#TEST 
    RETURN 
END TRY 
BEGIN CATCH 
    exeC#HandleError 
END CATCH; 
-1

Это ваше ВОЗВРАЩЕНИЕ: «Выходит безоговорочно из запроса или процедуры. RETURN является немедленным и полным и может использоваться в любой момент для выхода из процедуры, пакета или оператора».

+0

«RETURN» не достигнут, как указано «Имя столбца» или количество заданных значений не соответствует определению таблицы. «Ошибка ... –

+0

Спасибо Расселу - хотя я согласен с Майклом, я честно определенное возвращение не достигается. Спасибо всем за помощь в этом - я думаю, что у Ивана есть ответ выше. – DanBennett

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