Aqui está parte de um modelo de procedimento armazenado que eu uso:
/* CREATE PROCEDURE... */
DECLARE
@ErrorMessage varchar(2000)
,@ErrorSeverity tinyint
,@ErrorState tinyint
/* Additional code */
BEGIN TRY
/* Your code here */
END TRY
BEGIN CATCH
SET @ErrorMessage = ERROR_MESSAGE()
SET @ErrorSeverity = ERROR_SEVERITY()
SET @ErrorState = ERROR_STATE()
RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState)
BREAK
END CATCH
/* Further cleanup code */
Os blocos Try/Catch podem ser complicados, mas são muito mais completos do que @@error. Mais importante, você pode usar as várias funções error_xxx() dentro delas. Aqui, armazeno a mensagem de erro adequada na variável @ErrorMessage, juntamente com outros dados suficientes para aumentar novamente o erro. A partir daqui, qualquer número de opções está disponível; você pode tornar @ErrorMessage uma variável de saída, testar e lidar com erros específicos ou criar suas próprias mensagens de erro (ou ajustar as existentes para serem mais claras - você pode ficar irritado ao descobrir com que frequência deseja fazer isso). Outras opções se apresentarão.
Algo a ser observado:em algumas situações, o SQL lançará duas mensagens de erro consecutivas ... e
error_message()
só pegará o último, que geralmente diz algo como "tentativa de criação de objeto falhou", com o erro real dado na primeira mensagem de erro. É aqui que entra a criação de sua própria mensagem de erro.