login à la table dans le triggersur SQL Server

Je code le triggersur SQL Server 2005. Je veux faire de la journalisation pendant l'exécution du triggersur, en utilisant l'instruction INSERT dans ma table de journal. En cas d'erreur lors de l'exécution, je souhaite triggersr une erreur et annuler une action qui provoque l'exécution du sortinggger, mais ne pas perdre les loggings du journal. Quel est le meilleur moyen d'y parvenir?

Maintenant, mon triggersur 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 à ceci:

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

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 command ROLLBACK TRANSACTION est donnée. L'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' 

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

Deux options me viennent à l'esprit:

  • utiliser Service Broker pour la journalisation – mettre datatables du journal en queue, recevoir et save datatables 'de l'autre côté du tuyau' (c'est-à-dire dans un autre process / connection / transaction)
  • utilisez OPENQUERY – vous aurez besoin d'save votre propre server en tant que 'server lié' et d'exécuter des requêtes 'à distance' (je sais, cela semble un peu étrange, mais une option de toute façon …)

HTH

Je ne sais pas si je pense trop simple, mais pourquoi ne pas simplement changer l'ordre du gestionnaire d'erreur à insert après la restauration?

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

Gestion des erreurs de vérification dans les triggersurs .