Eine der beliebtesten frei verfügbaren Integration Services Komponenten ist zweifelsohne die Dimension Merge SCD Komponente, zu finden auf Codeplex unter http://dimensionmergescd.codeplex.com/. Als Alternative zum Standard Slowly Changing Dimension (SCD) Wizard der Integration Services, bietet die Komponente bessere Performance, Stabilität und diverse erweiterte Konfigurationsmöglichkeiten. Allerdings fehlt der Komponente eine simple Funktionalität: das Durchreichen einer Eingangsspalte ohne jegliche SCD Behandlung, auch genannt “SCD Type 0” oder “Pass Through”.
Dieses Problem wurde bereits mehrfach in diversen Diskussionen oder Change Requests auf Codeplex aufgeworfen, so z.B. hier, hier und hier. Leider haben die Entwickler der Komponente bisher keine Lösung für diese Anforderung liefern können. Mehrfach wird (berechtigterweise) die Frage aufgeworfen wie das Business Szenario für solch eine Anforderung aussehen könnte. Schließlich handelt es sich um eine SCD Komponente, d.h. die Möglichkeiten der Komponente sind ein Stück weit schon per Definition von SCDs vorgegeben.
Was die Entwickler dabei aber vergessen ist, dass die Komponente meist in einen größeren Integrationsprozess eingebunden ist, d.h. es gibt unter Umständen Anforderungen an die Komponente die vom Prozess drumherum herrühren und nicht SCD-spezifischer Natur sind. Ein mögliches Szenario könnte z.B. sein, dass man anhand von ImportIDs nachverfolgen möchte, welcher Datensatz aus dem Quellsystem zu einer Änderung an einem Datensatz im DWH geführt hat. Dies hat per se nichts mit SCD zu tun, stellt aber eine typische Anforderung im Rahmen von Integrationsprozessen dar mit der die Komponente umgehen sollen könnte.
Im Folgenden zeige ich, wie man die Komponente dennoch dazu überreden kann eine Spalte durchzureichen, um diese anschließend für den eigenen Prozess weiter nutzen zu können. Als Beispiel soll hier eine simple Tabelle dienen, die in keinem DWH fehlen darf: DimFruit. Diese enthält neben den Spalten FruitID (Surrogate Key), FruitKey (Business Key) und FruitName (SCD Attribut) zwei weitere Spalten InsertImportID und UpdateImportID. Diese referenzieren Datensätze aus Lieferungen des Quellsystems und erlauben es, nachzuverfolgen mit welchem Quelldatensatz ein Insert bzw. ein Update stattgefunden haben. Hier ein Preview der DimFruit:
Soweit so gut – dem geneigten Hobby-DWH-Botaniker fällt allerdings sofort auf, dass eine Gurke wohl kaum eine Frucht sein kann?! In Rücksprache mit unserem Datenlieferanten wollen wir nun die DimFruit entsprechend aktualisieren, wir erhalten folgende Quellzeilen:
Wie man erkennen kann, wird der Apfel mit FruitKey A vom Quellsystem weiterhin geliefert. Die Frucht mit FruitKey C wurde dahingehend korrigiert, dass statt der Gurke eine Kokosnuss geliefert wird… aha. Hinzu gekommen ist die Frucht mit dem FruitKey O, nämlich die Orange. Ziel des nächsten Imports sollte nun sein eine SCD Behandlung durchzuführen mit:
- Keiner Änderung am FruitKey A
- Einem Update des FruitNames der FruitID 2 auf Coconut
- Einem Insert der Frucht mit dem FruitKey O
Grundsätzlich können wir dafür die Dimension Merge SCD Komponente nutzen, für die letzten beiden Fällen ist es allerdings notwendig, die ImportIDs 4 und 5 für das Update bzw. Insert in die DimFruit durch die Komponente zu führen. Und genau hier fangen die Probleme an. Die Komponente bietet an dieser Stelle keine Möglichkeit, eine Spalte 1:1 in einen oder mehrere Ausgänge zu übernehmen. Es muss zwangsläufig immer ein “SCD Column Type” definiert werden, ansonsten geht die Spalte verloren. An dieser Stelle behelfen wir uns mit folgendem Trick: wir selektieren aus der DimFruit (Existing Dimension) zusätzlich die UpdateImportID als ImportID, um in der Komponente ein Mapping erstellen zu können und definieren die Spalte ImportID als SCD1:
Dies hat zur Folge, dass wir im “New” Output die Spalte ImportID wie gewünscht nutzen können. Für den “Updated SCD1” Output ist allerdings noch zusätzliche Logik notwendig. Im Falle des Apfels (FruitKey A) wird nun nämlich eine SCD1 Änderung an der ImportID festgestellt (voher: 1, jetzt: 3), die in diesem Fall aber unerwünscht ist. Um genau diesen Fall abzufangen, ist ein Conditional Split Task notwendig der anhand der Spalte “Row Change Reason” ermittelt, ob es sich um eine “echte” SCD1 Änderung handelt oder nur um eine Änderung an der ImportID (die bei diesem Verfahren häufiger auftreten wird):
Der fertige Datenfluss sieht dann so aus:
Und führt wie gewünscht ein Insert und ein Update durch:
Damit ist unsere DimFruit auf dem neuesten Stand und Änderungen bzw. Einfügungen lassen sich über die ImportIDs komfortabel bis in die Quelldatenlieferungen nachverfolgen.
Bleibt noch die Frage offen: handelt es sich bei einer Kokosnuss um eine Frucht?! Eine Blitzrecherche hat ergeben: Während der Begriff “Frucht” im allgemeinen Sprachgebrauch gerne für Obst verwendet wird, handelt es sich bei der Kokosnuss im weiteren Sinne natürlich auch um eine Frucht, nämlich die Frucht der Kokospalme. Der Begriff “Nuss” ist an dieser Stelle irreführend, da es sich bei der Kokosnuss um eine Steinfrucht handelt. Ähnlich verhält es sich übrigens auch mit der Gurke, ebenfalls eine Frucht, welche zu den Panzerbeeren gehört!