J'écris une fonction définie par l'utilisateur dans SQL Server 2008. Je sais que les fonctions ne peuvent pas générer d'erreurs de la manière habituelle - si vous essayez d'inclure l'instruction RAISERROR, SQL renvoie:
Msg 443, Level 16, State 14, Procedure ..., Line ...
Invalid use of a side-effecting operator 'RAISERROR' within a function.
Mais le fait est que la fonction prend une entrée, qui peut être invalide et, si c'est le cas, il n'y a pas de valeur significative que la fonction peut renvoyer. Que dois-je faire alors?
Je pourrais, bien sûr, retourner NULL, mais il serait difficile pour tout développeur utilisant la fonction de résoudre ce problème. Je pourrais aussi provoquer une division par zéro ou quelque chose comme ça - cela générerait un message d'erreur, mais trompeur. Est-il possible que je puisse faire rapporter mon propre message d'erreur d'une manière ou d'une autre?
declare @error int; set @error = 'Error happened here.';
L'astuce habituelle consiste à forcer une division par 0. Cela soulèvera une erreur et interrompra l'instruction courante qui évalue la fonction. Si le développeur ou la personne de support connaît ce comportement, il est assez facile d'enquêter et de résoudre le problème, car l'erreur de division par 0 est considérée comme le symptôme d'un problème différent et non lié.
Aussi mauvais que cela puisse paraître à tout point de vue, malheureusement, la conception des fonctions SQL pour le moment ne permet pas de meilleur choix. L'utilisation de RAISERROR doit absolument être autorisée dans les fonctions.
la source
Suite à la réponse de Vladimir Korolev, l'idiome pour lancer conditionnellement une erreur est
la source
Je pense que le moyen le plus propre est d'accepter simplement que la fonction puisse retourner NULL si des arguments non valides sont passés. Tant que cela est clairement documenté, cela devrait être correct?
la source
RAISEERROR
ou@@ERROR
ne sont pas autorisés dans les UDF. Pouvez-vous transformer l'UDF en une procédure stricte?De l'article d'Erland Sommarskog Gestion des erreurs dans SQL Server - un contexte :
la source
La meilleure réponse est généralement la meilleure, mais ne fonctionne pas pour les fonctions de table en ligne.
MikeTeeVee a donné une solution à cela dans son commentaire sur la première réponse, mais cela nécessitait l'utilisation d'une fonction d'agrégation comme MAX, qui ne fonctionnait pas bien pour ma situation.
J'ai déconné avec une solution alternative pour le cas où vous avez besoin d'une table en ligne valorisée udf qui renvoie quelque chose comme select * au lieu d'un agrégat. Un exemple de code résolvant ce cas particulier est présenté ci-dessous. Comme quelqu'un l'a déjà souligné ... "JEEZ wotta hack" :) Je salue toute meilleure solution pour ce cas!
la source
Quelques personnes ont posé des questions sur le déclenchement d'erreurs dans les fonctions table, car vous ne pouvez pas utiliser le genre de choses " RETURN [cast non valide] ". L'affectation du cast invalide à une variable fonctionne aussi bien.
Cela se traduit par:
la source
Je ne peux pas commenter la réponse de davec concernant la fonction de table, mais à mon humble avis, c'est une solution plus simple:
la source
Une façon (un hack) est d'avoir une fonction / procédure stockée qui effectue une action non valide. Par exemple, le pseudo SQL suivant
Où sur la table tbl_throw_error, il y a une contrainte unique sur la colonne err_msg. Un effet secondaire de ceci (au moins sur MySQL), est que la valeur de err_msg est utilisée comme description de l'exception lorsqu'elle revient dans l'objet d'exception au niveau de l'application.
Je ne sais pas si vous pouvez faire quelque chose de similaire avec SQL Server, mais ça vaut le coup.
la source