Protokoll ändert sich in die Datenbanktabelle mit Trigger

8

Ich suche nach einer guten Möglichkeit, Änderungen zu protokollieren, die in einer bestimmten Gruppe von Tabellen in meiner SQL Server 2005-Datenbank auftreten. Ich glaube, der beste Weg, dies zu tun, ist durch einen Trigger, der bei Updates und Löschungen ausgeführt wird. Gibt es sowieso, um die tatsächliche Aussage, die ausgeführt wird, zu ergreifen? Sobald ich die Aussage habe, kann ich sie leicht an anderer Stelle (andere DB-Tabelle) anmelden. Ich habe jedoch keinen einfachen Weg gefunden (wenn möglich), die SQL-Anweisung zu übernehmen, die ausgeführt wird.

    
Jason 22.05.2009, 20:24
quelle

11 Antworten

1

Trigger sind schlecht, ich würde mich von Triggern fernhalten.

Wenn Sie versuchen, etwas zu beheben, hängen Sie SQL Profiler mit bestimmten Bedingungen an die Datenbank an . Dies protokolliert jede Abfrage für Ihre Inspektion.

Eine andere Option besteht darin, in aufrufendes Programm zu wechseln, um seine Abfragen zu protokollieren. Dies ist eine sehr übliche Praxis.

    
Andomar 22.05.2009, 21:17
quelle
7

Wenn Sie nur ein Protokoll aller Transaktionen (Einfügen, Aktualisieren und Löschen) in einigen Datenbanktabellen speichern möchten, können Sie das folgende Skript ausführen:

%Vor%     
Juan Carlos Velez 11.05.2011 22:07
quelle
5

Sie sollten dies mithilfe der Systemverwaltungsansichten erreichen können.

Ein Beispiel wäre etwa so:

%Vor%

Ich bin mir nicht sicher, ob dies für Sie so nützlich sein wird, wie es ein datenzentrierter Protokollierungsmechanismus sein könnte.

    
mwigdahl 22.05.2009 20:31
quelle
4

Vergessen Sie nicht, dass Ihre Protokollierung Teil der Transaktion sein wird. Wenn es einen Fehler gibt und Sie die Transaktion zurücksetzen, wird Ihr Protokoll ebenfalls gelöscht.

    
idstam 22.05.2009 20:47
quelle
2

MSSQL hat virtuelle Tabellen mit den Namen 'Eingeschaltet' und 'Gelöscht', die neu eingefügte und / oder neu gelöschte und / oder neu aktualisierte Datensätze enthalten, auf die Sie von einem Trigger aus zugreifen können ... Ich benutze diese, um zu wissen, welche Daten sich geändert haben (anstatt zu sagen, welche Anweisung die Daten geändert hat).

    
ChrisW 22.05.2009 20:31
quelle
2

Es gibt ein Muster zum Erstellen solcher Trigger namens Log Trigger . Dies ist herstellerunabhängig und sehr einfach. Es ist in hier beschrieben.

Die Änderungen werden in einer anderen Geschichte Tabelle aufgezeichnet. Es gibt keine Möglichkeit, die genaue Anweisung abzurufen, aber es ist möglich, zu erkennen, ob es sich um eine Einfügung und um eine Aktualisierung oder eine Löschung handelt, weil sie eine "verkettete" Menge von Datensätzen erstellt. Ein Einfügen ist ein Datensatz ohne Vorgänger, ein Löschen ist ein Datensatz ohne Nachfolger, Zwischensätze sind Aktualisierungen. Änderungen können erkannt werden, indem ein Datensatz mit seinem Vorgänger verglichen wird.

Es ist sehr einfach, einen Snapshot einer einzelnen Entität (oder der gesamten Tabelle) zu einem bestimmten Zeitpunkt zu erhalten.

Als Bonus ist die Syntax dieses Musters für SQL Server im Vergleich zu Oracle, DB2 und MySQL die einfachste.

    
user1309314 03.04.2012 01:04
quelle
1

Müssen Sie wirklich die ausgeführte Anweisung protokollieren, protokollieren die meisten Personen die geänderten Daten (INSERTED- und DELETED-Tabellen innerhalb des Triggers).

    
KM. 22.05.2009 20:31
quelle
1

Trigger stellen eine gute Möglichkeit dar, um sicherzustellen, dass alle Änderungen protokolliert werden, da sie fast immer ausgelöst werden, unabhängig davon, wie die Aktualisierungen durchgeführt werden - z. Ad-hoc-Verbindungen sowie Anwendungsverbindungen.

Wie von @mwigdahl vorgeschlagen, sehen die Systemverwaltungsansichten wie eine gute Möglichkeit zum Erfassen des aktuell laufenden Stapels aus. Ob das zum Anmelden des Triggers besonders nützlich ist, ist eine andere Sache.

Ein Nachteil von Triggern ist, dass Sie die Quelle des Updates nur über die Datenbankverbindung identifizieren können. Viele Anwendungen verfügen über keine Benutzerinformationen, die mit der Verbindung verknüpft sind, um das Verbindungs-Pooling zu erleichtern, sodass Sie nicht wissen, welcher Benutzer die Aktion ausführt. dh das Login, das von der Verbindung verwendet wird, ist eine Anmeldung für eine generische Anwendung und nicht die Person, die die Anwendung verwendet. Der normale Weg, dies zu umgehen, besteht darin, gespeicherte Prozeduren als Schnittstelle zu allen Datenbankinteraktionen zu verwenden und dann sicherzustellen, dass eine Benutzer-ID mit allen Prozeduraufrufen übergeben wird. Sie können dann Ihre Protokollierung über die gespeicherte Prozedur anstelle eines Triggers durchführen. Dies ist natürlich nur nützlich, wenn Sie wissen, dass Benutzer Tabellen nicht direkt aktualisieren, ohne die Prozeduren zu verwenden, oder diese Situation nicht protokollieren müssen.

Die Möglichkeit, den aktuell ausgeführten Batch zu erhalten, bietet möglicherweise einen noch besseren Mechanismus: Wenn Sie sicherstellen, dass alle Ihre SQL-Batches eine UserId enthalten, können Sie diese aus dem SQL innerhalb Ihres Triggers extrahieren. Dadurch können Sie die gesamte Protokollierung mit Triggern durchführen, was bedeutet, dass Sie alles erfassen, aber auch Änderungen einem bestimmten Benutzer zuordnen können.

Wenn Sie die Auslöserroute herunterfahren, sollten Sie prüfen, ob die Trigger für Situationen nicht ausgelöst werden (z. B. Daten, die in großen Mengen geladen wurden oder wenn Benutzer die Berechtigung zum Deaktivieren von Triggern haben).

Beachten Sie auch, dass @idstam darauf hingewiesen hat, dass der Trigger-Code innerhalb Ihrer Transaktion liegt. Daher wird er normalerweise protokolliert und zusammen mit diesem zurückgesetzt.

Eine weitere Sache, die beim Schreiben von Triggern zu beachten ist, ist das Verhalten von @@ IDENTITY : Wenn Sie Prozeduren mit @@ IDENTITY verwenden, können Sie ihr Verhalten versehentlich ändern.

    
Rory 22.05.2009 21:54
quelle
1

Verwenden Sie einen Protokollauslöser

Es gibt wenig Grund, das tatsächliche SQL zu erfassen, da es viele verschiedene Anweisungen gibt, die Daten auf die gleiche Weise ändern.

    
grokster 07.02.2013 20:20
quelle
0

Versuchen Sie, ein Trigger-basiertes Third-Party-Tool zu installieren, z. B. ApexSQL-Audit , und führen Sie dann ein Reverse-Engineering durch. Installieren Sie es einfach im Testmodus und sehen Sie, wie es Auslöser für das Erfassen aller Arten von Informationen generiert.

Mehrere andere Dinge zu beachten sind:

Speicherplanung - Wenn Sie viele Updates haben, bedeutet das, dass Sie eine Menge Auditdaten haben. Ich würde in Erwägung ziehen, diese Daten in separaten Datenbanken zu speichern. Vor allem, wenn Sie mehr als eine Datenbank überwachen möchten.

Verwaltung der Datenmenge - im Laufe der Zeit werden Sie wahrscheinlich nicht mehr sehr alte Datensätze aufbewahren müssen. Planen Sie das einfache Löschen alter Daten

Schemaänderungen - Was passiert, wenn das Schema aktualisiert wird? Im schlimmsten Fall hören Ihre Trigger auf zu arbeiten und geben einen Fehler aus, wenn sie nicht korrekt erstellt werden. Im besten Fall werden Sie einige der Daten verpassen. Dies ist auch etwas zu berücksichtigen.

Wenn man all dies in Betracht zieht, ist es wahrscheinlich am effektivsten, mit einer bereits entwickelten Lösung zu arbeiten, anstatt dies von Grund auf selbst zu erstellen.

    
Joel Cuff 17.04.2013 09:14
quelle
-4

Seien Sie vorsichtig, da Trigger auf der ROW-Ebene und nicht auf der SQL-Anweisungsebene ausgelöst werden. Wenn jemand also "DELETE FROM BIGTABLE" auslöst, wird Ihr Trigger für jede Zeile in dieser Tabelle ausgelöst (dies insbesondere im Hinblick auf die Tatsache, dass Sie die SQL-Anweisung, die die Operation ausgeführt hat, wissen möchten das heraus "für jede Reihe, die die Aussage betrifft).

    
Will Hartung 22.05.2009 21:59
quelle