Ao escrever procedimentos, ocasionalmente encontro situações nas quais desejo abortar o procedimento, mesmo que a situação não tenha necessariamente acionado um erro.
Digamos que, se eu não quiser que John execute este procedimento, eu faria algo assim:
IF @UserName = 'John'
BEGIN
RAISERROR('John, get out', 16, 1);
RETURN 1;
END
Eu realmente não tenho um bom motivo para retornar 1, é principalmente um resquício do script de shell e estou aberto a melhores maneiras de fazer isso.
Existe uma maneira melhor de retornar uma mensagem de erro e retornar o controle ao chamador para situações indesejadas que não sejam erros estritamente falando? Não estou interessado em reduzir a quantidade de caracteres ou linhas de código. Eu apenas tive um pressentimento dizendo "esta provavelmente não é a melhor maneira de resolver este problema" e fiquei curioso para saber se havia maneiras mais inteligentes de fazer isso.
Uma alternativa poderia ser sempre usar TRY/CATCH
, já que RAISERROR
com uma severidade de 1-19 passará o controle para a cláusula catch.
Exemplo:
BEGIN TRY
PRINT 'Before RAISERROR';
RAISERROR('Time for errors', 16, 1);
PRINT 'After RAISERROR'
END TRY
BEGIN CATCH
DECLARE @Msg NVARCHAR(255) = ERROR_MESSAGE()
PRINT 'Inside CATCH'
RAISERROR(@Msg, 16, 1)
END CATCH
Resultado:
Before RAISERROR
Inside CATCH
Msg 50000, Level 16, State 1, Line 13
Time for errors
Con: Requer a presença de TRY/CATCH
blocos.
Você pode usar
THROW
O acima é um pouco mais conciso, pois é apenas uma única instrução e não precisa do
RETURN
, então você também pode descartar oBEGIN
eEND