In einem Projekt wird für einen Workflow eine Checksumme auf dem SQL Server berechnet. Je nach dem ob die alte noch gleich ist oder nicht werden die Daten auf ein Ziehl synchronisiert. Könnte noch mit einem alten .NET WF BETA gelöst worden sein. Die Checksummer wird im Select mit SUM(CONVERT(float, BINARY_CHECKSUM(feld1, feld2))) AS Checksum berechnet. Das tut auch so weit so gut. Nun habe ich ein Problem. Es gibt ein Feld. Wenn ich den Wert von 5 auf 4 ändere gibt das keine Änderung in der Checksumme. In einer anderen Situation aber schon. Der Unterschied ist die selektierte Datenmenge. Einmal sind es 39 Records, hier tut es nicht, einmal sind es 5 Records. Bei fünf gibt es eine Checksummenänderung, bei den 39 nicht.
Ein Record besteht aus etwa 70 Feldern aus verschiedenen Datentypen.
Kann es sein, dass die Änderung in den grossen Datenmengen einfach untergeht? Gibt es unter SQL Server 2000 eine zuverlässigere Methode eine Checksumme zu berechnen?
Das Problem bei einer Checksummenfunktion ist, das Kollisionen auftreten können. Als Kollision bezeichnet man, wenn zwei verschiedene Ausgangswerte die selbe Checksumme erzeugen.
Als echte Alternative würde ich dir eine Update-Tricker empfehlen. Du kannst in dem Tricker mit der Funktion "Update(<Feld>)" überprüfen ob das Feld geändert wurde und entweder direkt die Syncronisierung antrickern oder eine Tabelle / Flag an die Zeile schreiben.
CREATE TABLE my_table ( a varchar(10), b varchar(10) )
CREATE TRIGGER my_trig ON my_table FOR Update AS IF UPDATE(b) PRINT 'Column b Modified' GO /* Ich bin mir nicht ganz sicher ob UPDATE(b) nur gefeuert wird, wenn b auch wirklich modifierzit wurde oder immer dann wenn b im Update-Stament enthalten ist. Ggf. muss der neue Werte mit dem alten nochmal verglichen werden. */
Du könntest jetzt zum Beispiel anstelle von "PRINT 'Column b Modified'" ein Update auf eine andere Tabelle machen, oder du fügst in my_table noch eine Spalte "Last_Change" ein und schreibst bei einer Änderung hier z.b. ein Datum rein. Natürlich muss der Sync-Mechanismus das Datum wieder entfernen sobald er mit der Zeile fertig ist. Zu guter letzt kannst du auch eine zweite Tabelle dafür verwenden.
Was mir dabei noch einfällt wäre:
if BINARY_CHECKSUM(feld1, feld2)<>BINARY_CHECKSUM(feld1, feld2) or CHECKSUM(feld1, feld2)<>CHECKSUM(feld1, feld2) Print 'Änderung erkannt'
Wenn BINARY_CHECKSUM einer Kollision erliegt, muss das CHECKSUM nicht zwangläufig auch.
Leider ist der SQL-2000 Server etwas beschränkt. Hab das selbe Problem hier auf Arbeit auch. Zumindest konnten wir aber unsere Chefs überzeugen in absehbarer Zeit auf SQL-2008 umzusteigen. Da gibt es viele schön neue Funktionen (automatische Historie etc). Btw zum Thema Tricker: Text, Image und Binaryfelder stehen im SQL-2000 innerhalb des Trickers nicht zur Verfügung.
Na ja. Ob ich alles auf Trigger umbauen will ...