2010-02-08 3 views
1

OK, je ne suis pas si expérimenté avec la gestion des erreurs SQL 2005 et suis apprendre mon chemin autour des instructions try/catch.SQL 2005 try/catch bloc n'atteint jamais 'attraper' despte faux tests de données

J'ai écrit la procédure ci-dessous mais peu importe ce que je lui passe, il n'y a jamais de données dans ma table ErrorLog. J'ai passé toutes les valeurs INT , toutes les valeurs datetime, ou les chaînes de données qui ne sont pas dans le DB et obtenir 0 lignes effectuées avec rien signalé dans ErrorLog. C'est comme si l'instruction CATCH n'est jamais atteinte (pour ce que ça vaut, j'ai aussi essayé de commenter la validation en haut).

Des idées de ce que je fais mal? Merci.

ALTER PROCEDURE [dbo].[aspnet_Membership_UpdateLastActivityDate] 

@UserId nvarchar(256), 
@UserName nvarchar(256), 
@LastActivityDate datetime, 
@ApplicationName nvarchar(256) 

AS 

DECLARE @Today DATETIME 
DECLARE @MSG VARCHAR(255) 
DECLARE @Severity INT 
DECLARE @ErrorCode INT 

BEGIN 

SET XACT_ABORT ON -- (I have also tried it without XACT_ABORT. No difference) 

BEGIN TRY 

    SET @ErrorCode = 0 
    SELECT @Today = GetDate() 

    IF (@UserId IS NULL) 
    RETURN(1) 

    IF (@UserName IS NULL) 
    RETURN(1) 

    IF (@LastActivityDate IS NULL) 
    RETURN(1) 

    BEGIN TRAN 
     UPDATE dbo.aspnet_Users WITH (ROWLOCK) 
     SET LastActivityDate = @LastActivityDate 
     FROM dbo.aspnet_Users u 
     INNER JOIN dbo.aspnet_Applications a 
     ON u.ApplicationId = a.ApplicationId 
     WHERE u.UserName = @UserName 
     AND u.UserId = @UserId 
     AND a.ApplicationName = @ApplicationName 
    COMMIT TRAN 

END TRY 
BEGIN CATCH 

    IF @@TRANCOUNT > 0 
     ROLLBACK TRAN 

    SET @ErrorCode = Error_Number() 
    SET @Severity = Error_Severity() 
    SET @MSG = 'An error was thrown: ' 
     + 'Error(' + @ErrorCode + '):' + ERROR_MESSAGE() 
     + ' Severity = ' + ERROR_SEVERITY() 
     + ' State = ' + ERROR_STATE() 
     + ' Procedure = ' + ERROR_PROCEDURE() 
     + ' Line Number = ' + ERROR_LINE() 

    INSERT INTO [dbo].[ErrorLog]([errornum], [errortype], [errormsg],[errorsource], [errordate]) 
    VALUES (@ErrorCode, 'E', @MSG, Error_Procedure(), @Today) 

    RAISERROR(@MSG, @Severity, 2) 

END CATCH 

END 

RETURN @ErrorCode 
+0

Merci, Code Sherpa, pour le choix ma réponse comme "la réponse". –

Répondre

2

Il a été pendant quelque temps depuis que je l'ai fait beaucoup avec la manipulation d'erreur SQL mais je ne vois pas un endroit qui est susceptible de générer une erreur. Vous attendez-vous à ce que les déclarations «Retour» soient «prises»? Cela n'arrivera pas ... ils reviendront juste de la fonction. Vous devrez générer une erreur et ne pas déclencher de retour.

+0

En d'autres termes: 'CATCH' n'est pas 'FINALLY'. Bonne réponse, cependant, +1. – Aaronaught

+0

C'est vrai @Aaronaught. La gestion des erreurs dans T-SQL est loin d'être terminée, mais elles progressent et j'espère voir des éléments de travail décents pour la prochaine version complète de SQL Server (par exemple après 2008 R2). –

+0

Merci pour votre aide Mark. Semble que je confondais la sélection d'erreurs procédurales select instruction (par exemple, quand une instruction renvoie null) avec des erreurs de bloc try-catch (par exemple, une table n'existe pas). Merci d'avoir éclairci ça pour moi. –

2

D'accord avec @Mark. Essayez de changer cette situation

IF (@UserId IS NULL) 
    RETURN(1) 

à ceci:

IF (@UserId IS NULL) 
BEGIN 
    RAISERROR('No UserID was passed in.', 11, 1); 
    RETURN 1; 
END 

Voir aussi cet article pour une amorce de gestion des erreurs fantastique par Erland Sommarskog:

http://www.sommarskog.se/error_handling_2005.html

+0

Merci pour le lien d'Erland Aaron. C'était extrêmement utile. Comme il n'y a pas d'option 'assist', je vous ai mis à jour. Merci encore! –