Estou escrevendo uma função definida pelo usuário no SQL Server 2008. Sei que as funções não podem gerar erros da maneira usual - se você tentar incluir a instrução RAISERROR, o SQL retornará:
Msg 443, Level 16, State 14, Procedure ..., Line ...
Invalid use of a side-effecting operator 'RAISERROR' within a function.
Mas o fato é que a função recebe alguma entrada, que pode ser inválida e, se for, não há valor significativo que a função possa retornar. O que eu faço então?
É claro que eu poderia retornar NULL, mas seria difícil para qualquer desenvolvedor que utilize a função solucionar esse problema. Eu também poderia causar uma divisão por zero ou algo assim - isso geraria uma mensagem de erro, mas enganosa. Existe alguma maneira de eu ter minha própria mensagem de erro relatada de alguma forma?
declare @error int; set @error = 'Error happened here.';
O truque usual é forçar uma divisão por 0. Isso gera um erro e interrompe a instrução atual que está avaliando a função. Se o desenvolvedor ou a pessoa de suporte souber desse comportamento, investigar e solucionar o problema é bastante fácil, pois o erro de divisão por 0 é entendido como sintoma de um problema diferente e não relacionado.
Por pior que isso pareça de qualquer ponto de vista, infelizmente o design das funções SQL no momento não permite uma melhor escolha. O uso de RAISERROR deve ser absolutamente permitido em funções.
fonte
Seguindo a resposta de Vladimir Korolev, o idioma para gerar um erro condicionalmente é
fonte
Eu acho que a maneira mais limpa é apenas aceitar que a função possa retornar NULL se argumentos inválidos forem passados. Enquanto isso estiver claramente documentado, tudo ficará bem?
fonte
RAISEERROR
ou@@ERROR
não são permitidos em UDFs. Você pode transformar o UDF em um procedimento estressado?Do artigo de Erland Sommarskog, Tratamento de erros no SQL Server - um histórico :
fonte
A resposta principal é geralmente melhor, mas não funciona para funções com valor de tabela embutida.
MikeTeeVee deu uma solução para isso em seu comentário sobre a resposta principal, mas exigiu o uso de uma função agregada como MAX, que não funcionou bem para a minha circunstância.
Eu brinquei com uma solução alternativa para o caso em que você precisa de uma tabela embutida com valor udf que retorne algo como select * em vez de um agregado. O código de exemplo que resolve este caso específico está abaixo. Como alguém já apontou ... "JEEZ wotta hack" :) Congratulo-me com qualquer solução melhor para este caso!
fonte
Algumas pessoas estavam perguntando sobre como gerar erros nas funções com valor de tabela, pois você não pode usar o tipo de coisa " RETURN [conversão inválida] ". Atribuir a conversão inválida a uma variável também funciona.
Isto resulta em:
fonte
Não posso comentar na resposta da davec sobre a função com valor de tabela, mas, na minha humilde opinião, essa é a solução mais fácil:
fonte
Uma maneira (um hack) é ter uma função / procedimento armazenado que executa uma ação inválida. Por exemplo, o seguinte pseudo SQL
Onde na tabela tbl_throw_error, há uma restrição exclusiva na coluna err_msg. Um efeito colateral disso (pelo menos no MySQL) é que o valor de err_msg é usado como descrição da exceção quando ele retorna ao objeto de exceção no nível do aplicativo.
Não sei se você pode fazer algo semelhante com o SQL Server, mas vale a pena tentar.
fonte