Wir verwenden CDC, um Änderungen an einer Produktionstabelle zu erfassen. Die geänderten Zeilen werden in ein Data Warehouse (informatica) exportiert. Ich weiß, dass die Spalte __ $ update_mask speichert, welche Spalten in einer varbinären Form aktualisiert wurden. Ich weiß auch, dass ich eine Vielzahl von CDC-Funktionen verwenden kann , um anhand dieser Maske herauszufinden, was diese Spalten waren.
Meine Frage ist dies. Kann jemand für mich die Logik hinter dieser Maske definieren, damit wir die Spalten identifizieren können, die im Lager umgestellt wurden? Da wir außerhalb des Servers verarbeiten, haben wir keinen einfachen Zugriff auf diese MSSQL CDC-Funktionen. Ich würde die Maske lieber selbst in Code zerlegen. Die Leistung der cdc-Funktionen auf SQL-Seite ist für diese Lösung problematisch.
Kurz gesagt, ich möchte geänderte Spalten von Hand aus dem Feld __ $ update_mask identifizieren.
Aktualisieren:
Als Alternative war es auch akzeptabel, eine von Menschen lesbare Liste geänderter Spalten an das Lager zu senden. Wir haben festgestellt, dass dies mit einer Leistung durchgeführt werden kann, die weit über unserem ursprünglichen Ansatz liegt.
Die unten stehende CLR-Antwort auf diese Frage erfüllt diese Alternative und enthält Details zur Interpretation der Maske für zukünftige Besucher. Die akzeptierte Antwort mit XML PATH ist jedoch die bisher schnellste für das gleiche Endergebnis.
quelle
Antworten:
Und die Moral der Geschichte ist ... testen, andere Dinge ausprobieren, groß denken, dann klein, immer davon ausgehen, dass es einen besseren Weg gibt.
So wissenschaftlich interessant wie meine letzte Antwort war. Ich beschloss, einen anderen Ansatz zu versuchen. Ich erinnerte mich, dass ich mit dem XML PATH ('') - Trick konatieren konnte. Da ich wusste, wie ich die Ordnungszahl jeder geänderten Spalte aus der Liste der erfassten Spalten aus der vorherigen Antwort ermitteln konnte, hielt ich es für sinnvoll, zu testen, ob die MS-Bit-Funktion auf diese Weise für das, was wir brauchten, besser funktioniert.
Es ist viel sauberer als (wenn auch nicht so unterhaltsam wie) die gesamte CLR und gibt den Ansatz nur für nativen SQL-Code zurück. Und Trommelwirbel ... liefert die gleichen Ergebnisse in weniger als einer Sekunde . Da die Produktionsdaten 100-mal größer sind, zählt jede Sekunde.
Ich lasse die andere Antwort für wissenschaftliche Zwecke offen - aber im Moment ist dies unsere richtige Antwort.
quelle
Nach einigen Recherchen haben wir uns daher entschlossen, dies weiterhin auf der SQL-Seite zu tun, bevor wir es an das Data Warehouse übergeben. Aber wir verfolgen diesen viel verbesserten Ansatz (basierend auf unseren Bedürfnissen und dem neuen Verständnis der Funktionsweise der Maske).
Mit dieser Abfrage erhalten wir eine Liste der Spaltennamen und ihrer Ordnungspositionen. Die Rückgabe erfolgt in einem XML-Format, damit wir sie an SQL CLR weitergeben können.
Wir übergeben diesen XML-Block dann als Variable und das Maskenfeld an eine CLR-Funktion, die eine durch Kommas getrennte Zeichenfolge der Spalten zurückgibt, die sich gemäß dem Binärfeld _ $ update_mask geändert haben. Diese clr-Funktion fragt das Maskenfeld nach dem Änderungsbit für jede Spalte in der XML-Liste ab und gibt dann den Namen von der zugehörigen Ordnungszahl zurück.
Der c # clr-Code sieht folgendermaßen aus: (kompiliert in eine Assembly namens CDCUtilities)
Und die Funktion zur CLR lautet wie folgt:
Anschließend hängen wir diese Spaltenliste an das Rowset an und übergeben sie zur Analyse an das Data Warehouse. Durch die Verwendung der Abfrage und des clr müssen keine zwei Funktionsaufrufe pro Zeile und Änderung verwendet werden. Wir können direkt zum Fleisch mit Ergebnissen springen, die für unsere Änderungserfassungsinstanz angepasst wurden.
Dank dieses von Jon Seigel vorgeschlagenen Stackoverflow-Beitrags für die Interpretation der Maske.
Nach unserer Erfahrung mit diesem Ansatz können wir in weniger als 3 Sekunden eine Liste aller geänderten Spalten aus 10.000 cdc-Zeilen abrufen.
quelle