Frage

Ich arbeite an einem Projekt, bei dem ich Daten von unserem System mit einem externen System synchronisieren muss. Was ich erreichen möchte, ist, regelmäßig nur geänderte Elemente (Zeilen) aus einer benutzerdefinierten Abfrage zu senden. Diese Abfrage sieht so aus (aber mit vielen weiteren Spalten):

SELECT T1.field1,
    T1.field2,
    T1.field2,
    T1.field3,
    CASE WHEN T1.field4 = 'some-value' THEN 1 ELSE 0 END,
    T2.field1,
    T3.field1,
    T4.field1
FROM T1
INNER JOIN T2 ON T2.pk = T2.fk
INNER JOIN T3 ON T3.pk = T2.fk
INNER JOIN T4 ON T4.pk = T2.fk

Ich möchte vermeiden, jedes Feld eins mit einem einzigen zwischen Synchronisierungen zu vergleichen. Ich kam mit der Idee, dass ich aus meiner Abfrage einen Hash für jede Zeile generieren und diesen mit dem Hash aus der vorherigen Synchronisation vergleichen kann, die nur die geänderten Zeilen zurückgibt. Ich bin mir dessen bewusst Überprüfung Funktion, aber es ist sehr kollisionsanfällig und kann manchmal Änderungen verpassen. Allerdings mag ich die Art, wie ich einfach einen Temperaturtisch machen und benutzen kann CHECKSUM(*), was die Wartung erleichtert (keine Felder in die Abfrage und in der Prüfsumme hinzufügen müssen):

SELECT T1.field1,
    T1.field2,
    T1.field2,
    T1.field3,
    CASE WHEN T1.field4 = 'some-value' THEN 1 ELSE 0 END,
    T2.field1,
    T3.field1,
    T4.field1
INTO #tmp
FROM T1
INNER JOIN T2 ON T2.pk = T2.fk
INNER JOIN T3 ON T3.pk = T2.fk
INNER JOIN T4 ON T4.pk = T2.fk;

-- get all columns from the query, plus a hash of the row
SELECT *, CHECKSUM(*)
FROM #tmp;

Ich bin mir bewusst, dass Hashbytes Funktion (die SHA1, MD5 unterstützt, die weniger anfällig für Kollisionen sind), akzeptiert jedoch nur VARCHAR oder VARBINARY, nicht eine Liste von Spalten oder * wie die Überprüfung. Jede Spalte aus der Abfrage zu werfen/zu konvertieren, ist ein Schmerz in der ... und öffnet die Tür zu Fehlern (vergessen Sie, beispielsweise ein neues Feld aufzunehmen).

Ich bemerkte auch Ändern Sie die Datenerfassung und ändern Sie die Verfolgung Funktionen von SQL Server, aber alle scheinen kompliziert und übertrieben für das, was ich tue.

Meine Frage: Gibt es eine andere Methode, um einen Hash aus einer Abfrage oder einer Temp -Tabelle zu generieren, die meinen Kriterien entspricht?

Wenn nicht, gibt es eine andere Möglichkeit, diese Art von Arbeit zu erreichen (um Unterschiede von einer Abfrage zu synchronisieren)

War es hilfreich?

Lösung

Ich fand einen Weg, genau das zu tun, was ich wollte, dank der FOR XML Klausel:

SELECT T1.field1,
    T1.field2,
    T1.field2,
    T1.field3,
    CASE WHEN T1.field4 = 'some-value' THEN 1 ELSE 0 END,
    T2.field1,
    T3.field1,
    T4.field1
INTO #tmp
FROM T1
INNER JOIN T2 ON T2.pk = T2.fk
INNER JOIN T3 ON T3.pk = T2.fk
INNER JOIN T4 ON T4.pk = T2.fk;

-- get all columns from the query, plus a hash of the row (converted in an hex string)
SELECT T.*, CONVERT(VARCHAR(100), HASHBYTES('sha1', (SELECT T.* FOR XML RAW)), 2) AS sHash
FROM #tmp AS T;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top