2010-05-11 7 views
4

Je suis en train de coder le déclencheur SQL Server 2005. Je veux faire de la journalisation pendant l'exécution du déclencheur, en utilisant l'instruction INSERT dans ma table de journal. En cas d'erreur lors de l'exécution, je souhaite déclencher une erreur et annuler une action qui provoque l'exécution du trigger, mais ne pas perdre les enregistrements du journal. Quel est le meilleur moyen d'y parvenir?Connexion à la table dans le déclencheur SQL Server

Maintenant, mon déclencheur enregistre tout sauf la situation en cas d'erreur - à cause de ROLLBACK. L'instruction RAISERROR est nécessaire pour informer le programme appelant de l'erreur.

Maintenant, mon code de gestion des erreurs ressemble:

if (@err = 1) 
begin 
    INSERT INTO dbo.log(date, entry) SELECT getdate(), 'ERROR: ' + out from #output 
    RAISERROR (@msg, 16, 1) 
    rollback transaction 
    return 
end 

Répondre

7

Une autre option possible consiste à utiliser une variable de table pour capturer les informations que vous souhaitez stocker dans votre table de journal permanente. Les variables de table ne sont pas annulées si une commande ROLLBACK TRANSACTION est donnée. Exemple de code est ci-dessous ...



--- Declare table variable 
DECLARE @ErrorTable TABLE 
    ([DATE] smalldatetime, 
    [ENTRY] varchar(64)) 

DECLARE @nErrorVar int 

--- Open Transaction 
BEGIN TRANSACTION 

--- Pretend to cause an error and catch the error code 
SET @nErrorVar = 1 --- @@ERROR 

IF (@nErrorVar = 1) 
    BEGIN 

    --- Insert error info table variable 
    INSERT INTO @ErrorTable 
     ([Date], [Entry]) 
    SELECT 
     getdate(), 'Error Message Goes Here' 

    RAISERROR('Error Message Goes Here', 16, 1) 

    ROLLBACK TRANSACTION 

    --- Change this to actually insert into your permanent log table 
    SELECT * 
    FROM @ErrorTable 

    END 

IF @@TRANCOUNT 0 
    PRINT 'Open Transactions Exist' 
ELSE 
    PRINT 'No Open Transactions' 
+0

C'est ce que nous faisons – HLGEM

+0

En effet. J'ai raté cette option, mais votez pour cela. – AlexS

2

Le problème ici est que l'exploitation forestière fait partie de la transaction qui modifie vos données. Les transactions imbriquées n'aideront pas ici. Ce dont vous avez besoin, c'est de vous placer dans un contexte séparé (connexion), c'est-à-dire de le rendre indépendant de votre transaction actuelle.

Deux options viennent à l'esprit:

  • utilisation Service Broker pour l'enregistrement - mettre les données du journal à la file d'attente, recevoir et enregistrer les données « de l'autre côté du tuyau » (dans un autre processus/connexion/transaction)
  • utilisation OPENQUERY - vous devez vous inscrire propre serveur comme un « serveur lié » et exécuter des requêtes à distance « » (je sais, cela ressemble un peu étrange, mais une option quand même ...)

HTH

2

Je ne sais pas si je pense trop simple, mais pourquoi ne pas simplement changer l'ordre du gestionnaire d'erreur pour insérer après la rollback ??

if (@err = 1) 
begin 
    RAISERROR (@msg, 16, 1) 
    rollback transaction 
    INSERT INTO dbo.log(date, entry) SELECT getdate(), 'ERROR: ' + out from #output 
    return 
end 
+0

Votez +1 par simplicité XD –

Questions connexes