Estou experimentando um comportamento THROW
que não consigo entender. Considere o seguinte procedimento armazenado:
CREATE PROCEDURE usp_division_err AS
SET NOCOUNT ON;
BEGIN TRY
EXEC('select 1/0')
END TRY
BEGIN CATCH
THROW;
END CATCH
Quando o procedimento é executado, o seguinte erro é gerado:
Msg 8134, Nível 16, Estado 1, Linha 1
Erro de divisão por zero encontrado.
Observe que nenhuma informação sobre em qual procedimento o erro foi gerado está incluída. Isso ocorre porque o SQL dinâmico e incorreto é executado em outro escopo, e tudo bem. No entanto, altere o CATCH
-block para ficar assim
BEGIN CATCH
THROW 50000, 'An error occurred.', 1;
END CATCH
e a execução do procedimento gerará este erro:
Msg 50000, Nível 16, Estado 1, Procedimento usp_division_err, Linha 7 [Batch Start Line 0]
Ocorreu um erro.
O erro ainda é encontrado durante a execução do SQL dinâmico, mas quando eu especifico manualmente o número do erro e a mensagem de erro (o primeiro e o segundo parâmetro de THROW
), o nome do procedimento do procedimento em execução aparece de alguma forma.
Por que o nome do procedimento aparece na segunda mensagem de erro, mas não na primeira?
Codifique
CATCH
assim:Isso permite que você passe todos os parâmetros para a
THROW
instrução para que ela possa enviá-los de volta ao chamador.Eu testei assim:
Os resultados:
Para obter o número do erro nativo, você só precisa subtrair 50000 do número do erro relatado. Como os parâmetros para
THROW
são opcionais, deve haver dois caminhos de código dentroTHROW
de , um que informa o nome do procedimento e outro que não. Vou deixar para o leitor decidir qual caminho de código faz isso.