2009-12-18 6 views
5

Nous ajoutons des procédures stockées à notre produit qui peuvent être appelées par des clients tiers. Existe-t-il des bonnes pratiques pour la validation des paramètres, les valeurs de retour, RAISERROR, etc?Meilleures pratiques pour l'API de procédure stockée?

Les clients tiers n'auront pas d'accès direct à la table, uniquement pour certains sprocs. La table touchée par les sprocs est bien limitée mais nous voulons être aussi conviviaux que possible en fournissant des informations d'erreur détaillées lorsque les sprocs sont appelés de manière incorrecte.

+1

Bonne question! –

Répondre

2

Il n'est pas difficile de fournir des messages d'erreur d'information qu'un humain peut comprendre. Juste RAISERROR avec un texte descriptif. un peu plus difficile est d'élever des textes localisés, ce qui implique une utilisation correcte de la sp_addmessage et de la famille. Le vrai problème consiste à soulever une erreur à laquelle un programme peut réagir. Cela signifie que les codes d'erreur correctement documentés (et sévérité et état), et une sévère discipline de code dans leur utilisation dans votre API. Et n'oublie pas l'imbrication correcte des transactions. J'ai un exemple sur mon blog sur la façon de gérer correctement les transactions en combinaison avec les exceptions T-SQL: Exception handling and nested transactions.

Malheureusement, l'état de la technique sur l'ensemble de la pile client/pile T-SQL à l'exception de quelques problèmes. Le plus notable est que si vous interceptez une exception T-SQL, vous ne pouvez pas la renvoyer, de sorte que votre client ne peut pas s'attendre aux numéros d'erreur système typiques. Voir SQL Server: Rethrow exception with the original exception number. Cela vous laisse peu de moyens de communiquer des informations d'erreur correctes, autres que d'utiliser vos propres numéros d'erreur sur plus de 50000, ce qui est très lourd lorsque le nombre de codes d'erreur 'transalés' augmente, et utilise la chaîne de message d'erreur comme information d'exception .

+0

Y a-t-il des problèmes d'interopérabilité avec des clients non-Windows? Il y a peu de mention de manipulation de RAISERROR dans leurs documents. –

+0

Pas que je sache. RAISERROR soulève le même type d'erreur que les erreurs système, et FreeTDS sait comment les gérer. –

3
  • Utilisez try/blocs CAPTURE
  • Throw messages significatifs (j'utiliser un préfixe tel que "INFO:" pour distinguer mes erreurs d'erreurs de base de données)

Exemple:

SET NOCOUNT, XACT_ABORT ON 
... 
BEGIN TRY 
    IF @parameter1 IS NULL 
     RAISERROR ('INFO: "parameter1" should not be blank', 16, 1) 

    IF @parameter2 < 0 
     RAISERROR ('INFO: "parameter2" must be greate then zero', 16, 1) 

    ... 

END TRY 
BEGIN CATCH 
    DECLARE @MyError nvarchar(2048) 
    SELECT @MyError = ERROR_MESSAGE() -- + other stuff, like stored proc name perhaps 
    RAISERROR (@MyError, 16, 1) 
    ... 
END CATCH 
+1

Vous devez définir un état différent pour chaque RAISERROR: (..., 16, ** 1 **), (..., 16, ** 2 **), (..., 16, ** 3 **). De cette façon, lorsqu'un client appelle le support et donne une information d'erreur (message, code, gravité, état) le support peut rapidement localiser exactement quel endroit a provoqué l'erreur, ce qui est exactement le but de l'état. –

+0

Nous le faisons légèrement plus complexe, y compris en enregistrant chaque erreur et en séparant ERROR d'INFO. Objet de journalisation, objet d'erreur, numéro de ligne etc. Mais: nous séparons les erreurs réelles de "oops, duplicate value" qui sont informatives et pas vraiment d'erreurs – gbn