Nach Änderungen an einer SQL Server-Tabelle suchen?

Translate

Wie kann ich eine SQL Server-Datenbank auf Änderungen an einer Tabelle überwachen, ohne Trigger zu verwenden oder die Struktur der Datenbank in irgendeiner Weise zu ändern? Meine bevorzugte Programmierumgebung ist.NETZund C#.

Ich würde gerne jeden unterstützen könnenSQL Server 2000SP4 oder neuer. Meine Anwendung ist eine integrierte Datenvisualisierung für das Produkt eines anderen Unternehmens. Unser Kundenstamm liegt bei Tausenden, daher möchte ich nicht bei jeder Installation die Anforderungen stellen müssen, dass wir die Tabelle des Drittanbieters ändern.

Durch"Änderungen an einer Tabelle"Ich meine Änderungen an Tabellendaten, keine Änderungen an der Tabellenstruktur.

Letztendlich möchte ich, dass die Änderung ein Ereignis in meiner Anwendung auslöst, anstatt in regelmäßigen Abständen nach Änderungen suchen zu müssen.


Die beste Vorgehensweise angesichts meiner Anforderungen (keine Trigger oder Schemaänderungen, SQL Server 2000 und 2005) scheint die Verwendung von zu seinBINARY_CHECKSUMFunktion inT-SQL. Die Art und Weise, wie ich sie implementieren möchte, ist folgende:

Führen Sie alle X Sekunden die folgende Abfrage aus:

SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*))
FROM sample_table
WITH (NOLOCK);

Und vergleichen Sie das mit dem gespeicherten Wert. Wenn sich der Wert geändert hat, gehen Sie die Tabelle Zeile für Zeile mit der folgenden Abfrage durch:

SELECT row_id, BINARY_CHECKSUM(*)
FROM sample_table
WITH (NOLOCK);

Und vergleichen Sie die zurückgegebenen Prüfsummen mit gespeicherten Werten.

This question and all comments follow the "Attribution Required."

Alle Antworten

Translate

Schauen Sie sich den Befehl CHECKSUM an:

SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) FROM sample_table WITH (NOLOCK);

Dies gibt bei jeder Ausführung dieselbe Nummer zurück, solange sich der Tabelleninhalt nicht geändert hat. Weitere Informationen finden Sie in meinem Beitrag dazu:

CHECKSUM

So habe ich es verwendet, um Cache-Abhängigkeiten wiederherzustellen, wenn sich Tabellen geändert haben:
Abhängigkeit des ASP.NET 1.1-Datenbankcaches (ohne Trigger)

Quelle
Translate

Leider funktioniert CHECKSUM nicht immer richtig, um Änderungen zu erkennen.

Es handelt sich nur um eine primitive Prüfsumme und keine CRC-Berechnung (Cyclic Redundancy Check).

Daher können Sie damit nicht alle Änderungen erkennen, z. B. führen symmetrische Änderungen zu derselben CHECKSUM!

Z.B. die Lösung mitCHECKSUM_AGG(BINARY_CHECKSUM(*))liefert immer 0 für alle 3 Tabellen mit unterschiedlichem Inhalt:


SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) FROM 
(
  SELECT 1 as numA, 1 as numB
  UNION ALL
  SELECT 1 as numA, 1 as numB
)  q
-- delivers 0!

SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) FROM ( SELECT 1 as numA, 2 as numB UNION ALL SELECT 1 as numA, 2 as numB ) q -- delivers 0!

SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) FROM ( SELECT 0 as numA, 0 as numB UNION ALL SELECT 0 as numA, 0 as numB ) q -- delivers 0!

Quelle
Translate

Warum möchten Sie keine Trigger verwenden? Sie sind eine gute Sache, wenn Sie sie richtig verwenden. Wenn Sie sie als Mittel zur Durchsetzung der referenziellen Integrität verwenden, wechseln sie von gut zu schlecht. Wenn Sie sie jedoch zur Überwachung verwenden, gelten sie nicht wirklich als Tabu.

Quelle
Translate

Wie oft müssen Sie nach Änderungen suchen und wie groß (in Bezug auf die Zeilengröße) sind die Tabellen in der Datenbank? Wenn Sie die verwendenCHECKSUM_AGG(BINARY_CHECKSUM(*))Die von John vorgeschlagene Methode scannt jede Zeile der angegebenen Tabelle. DasNOLOCKHinweis hilft, aber in einer großen Datenbank treffen Sie immer noch jede Zeile. Sie müssen auch die Prüfsumme für jede Zeile speichern, damit Sie feststellen können, dass sich eine geändert hat.

Haben Sie darüber nachgedacht, dies aus einem anderen Blickwinkel zu betrachten? Wenn Sie das Schema nicht ändern möchten, um Trigger hinzuzufügen (was sinnvoll ist, es ist nicht Ihre Datenbank), haben Sie darüber nachgedacht, mit dem Anwendungsanbieter zusammenzuarbeiten, der die Datenbank erstellt?

Sie könnten eine API implementieren, die einen Mechanismus zum Benachrichtigen von Zubehör-Apps bereitstellt, wenn sich Daten geändert haben. Es könnte so einfach sein, in eine Benachrichtigungstabelle zu schreiben, in der aufgeführt ist, welche Tabelle und welche Zeile geändert wurden. Dies könnte durch Trigger oder Anwendungscode implementiert werden. Von Ihrer Seite aus wäre das egal, Ihr einziges Anliegen wäre es, die Benachrichtigungstabelle regelmäßig zu scannen. Der Leistungseinbruch in der Datenbank wäre weitaus geringer als das Scannen jeder Zeile nach Änderungen.

Der schwierige Teil wäre, den Anwendungsanbieter davon zu überzeugen, diese Funktion zu implementieren. Da dies vollständig über SQL über Trigger erledigt werden kann, können Sie den Großteil der Arbeit für sie erledigen, indem Sie die Trigger schreiben und testen und dann den Code zum Anwendungsanbieter bringen. Indem der Anbieter die Trigger unterstützt, wird verhindert, dass das Hinzufügen eines Triggers versehentlich einen vom Anbieter bereitgestellten Trigger ersetzt.

Quelle
Translate

Leider glaube ich nicht, dass es in SQL2000 einen sauberen Weg gibt, dies zu tun. Wenn Sie Ihre Anforderungen auf SQL Server 2005 (und höher) beschränken, sind Sie im Geschäft. Du kannst den ... benutzenSQLDependencyKlasse inSystem.Data.SqlClient. SehenAbfragebenachrichtigungen in SQL Server (ADO.NET).

Quelle
Translate

Haben Sie einen DTS-Job (oder einen Job, der von einem Windows-Dienst gestartet wird), der in einem bestimmten Intervall ausgeführt wird. Jedes Mal, wenn es ausgeführt wird, erhält es mithilfe des Systems Informationen über die angegebene TabelleINFORMATION_SCHEMATabellen und zeichnet diese Daten im Datenrepository auf. Vergleichen Sie die Daten, die bezüglich der Struktur der Tabelle zurückgegeben wurden, mit den Daten, die beim letzten Mal zurückgegeben wurden. Wenn es anders ist, wissen Sie, dass sich die Struktur geändert hat.

Beispielabfrage zur Rückgabe von Informationen zu allen Spalten in Tabelle ABC (im Idealfall werden nur die Spalten aus der Tabelle INFORMATION_SCHEMA aufgelistet, die Sie möchten, anstatt wie hier * select ** zu verwenden):

select * from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'ABC'

Sie würden verschiedene Spalten und INFORMATION_SCHEMA-Ansichten überwachen, je nachdem, wie genau Sie "Änderungen an einer Tabelle" definieren.

Quelle
Translate

Wilde Vermutung hier: Wenn Sie die Tabellen von Drittanbietern nicht ändern möchten, können Sie eine Ansicht erstellen und dann einen Auslöser für diese Ansicht setzen?

Quelle
ECE
Translate

Überprüfen Sie das letzte Festschreibungsdatum. Jede Datenbank hat einen Verlauf, wann jedes Commit durchgeführt wird. Ich glaube, es ist ein Standard für die Einhaltung von Säuren.

Quelle