Beim täglichen ETL-Prozess der transaktionalen Daten ins Data Warehouse kann es dazu kommen, dass die Daten nicht jeden Tag geliefert werden. Abhängig davon sollen Prozesse wie z. B. „Automatischer Versand von DeltaMaster-Berichten“ ausgeführt werden.
Sicher sind Sie schon mit DeltaMaster vertraut und vielleicht benutzen Sie auch unseren ReportServer für automatisierte Berichtsgenerierung und deren Versand. Nehmen wir einmal an, dass ein Bericht erstellt wurde, der den Tagesumsatz aller Vertriebsmitarbeiter präsentiert. Im ReportServer wurde ein Job angelegt, der diesen Bericht für jeden Vertriebsmitarbeiter iteriert und via E-Mail verschickt. Allerdings soll vermieden werden, dass der Vertriebsmitarbeiter den Bericht erhält, wenn keine Fakturadaten für den Vortag vorliegen.
Dies kann üblicherweise sonntags der Fall sein, weil samstags keine Rechnungsdaten erzeugt werden. Auch kann es beim täglichen Ladeprozess zu Fehlern kommen. In diesem Fall dürften auch keine Berichte verschickt werden.
In diesem Artikel stellen wir Ihnen mithilfe von SSIS (SQL Server Integration Services) vor, wie man “ereignisgesteuert” Prozesse ausführt.
Implementierungsansätze in einem Data Warehouse (DWH)
Es werden folgende zwei Methoden vorgestellt:
Dateiprüfung
Bei diesem Vorgehen wird das Vorhandensein einer Datei (Fakturadaten) geprüft und das Ergebnis in eine Variable geschrieben. Der Inhalt der Variablen entscheidet später, ob der ReportServer-Job, in unserem Beispiel, oder welche Aktion auch immer ausgeführt wird oder nicht.
Wir erstellen ein SSIS-Paket und definieren auf „Paketebene“ (Rechtsklick im Design-Bereich – Variable) zwei Variablen vom Typ „String“ und „Boolean“. Als Standardwert erhält die Variable „FakturaFile“ den Pfad und den Dateinamen der Datei, deren Existenz geprüft werden soll. Die Variable „FileExists“ bekommt den Boolean-Wert „False“.
Für das SSIS-Paket legen wir zwei Tasks an:
Die Eigenschaften des Tasks „Dateiexistenz prüfen“ legen wir wie folgt fest:
Die Eigenschaft „EntryPoint“ gibt den Einstiegspunkt ein. Dies ist der VB-Code, der für die Zuweisung der Variable sorgt (SQL 2008):
Public Sub Main() ' ' Add your code here ' If System.IO.File.Exists(CStr(Dts.Variables("FakturaFile").Value)) Then Dts.Variables("FileExists").Value = True Else Dts.Variables("FileExists").Value = False End If Dts.TaskResult = ScriptResults.Success End Sub Bei SQL 2005 sieht der VB-Code so aus: Public Sub Main() ' ' Add your code here ' If System.IO.File.Exists(CStr(Dts.Variables("XLSfile").Value) & ".Check") Then Dts.Variables("FileExists").Value = 1 Else Dts.Variables("FileExists").Value = 0 End If Dts.TaskResult = Dts.Results.Success End Sub
Die Eigenschaft „ReadOnlyVariables“ gibt eine durch Trennzeichen getrennte Liste mit Variablen für den Lesezugriff an. Das heißt, es wird der Inhalt der Variablen „FakturaFile“ auf Existenz geprüft.
Die Eigenschaft „ReadWriteVariables“ gibt eine durch Trennzeichen getrennte Liste mit Variablen für den Lese- und Schreibzugriff an – also die Variable „FileExists“, die je nach Existenz der Fakturadatei auf „False“ oder „True“ gesetzt wird.
Die Verbindung des SQL-Tasks mit dem nächsten, bedingt auszuführenden Schritt findet dann über Variablenausdruck statt. Wie weiter oben zu sehen ist, handelt es sich bei dem Verbindungspfeil (blau) zwischen den beiden Tasks um eine spezielle, sogenannte „Ausdrucksverbindung“. Die Verbindung wird folgendermaßen bearbeitet:
Als Auswertungsvorgang wird der Standardwert „Einschränkung“ auf „Ausdruck“ geändert. Im Feld „Ausdruck“ verwendet man dann die angelegte Variable „@FileExists“ mit der Bedingung „==True“. Das bedeutet, der nächste Schritt nur dann ausgeführt wird, wenn der Ausdruck erfüllt ist. Es ist zu beachten, dass bei SQL 2005 die Bedingung als “@FileExists==1″ definiert werden muss.
In unserem Beispiel werden im zweiten Task alle täglichen ReportServer-Jobs ausgeführt.
Folgende Besonderheiten müssen beachtet werden:
– Variablennamen sind “case sensitive”.
– Datentypen (Variablen vs. Code bzw. SQL) müssen übereinstimmen. Es ist keine implizite Konvertierung möglich.
Prüfung von SQL-Ausdrücken
In diesem Fall wird durch einfache SQL-Anweisungen das letzte vorhandene Rechnungsdatum aus der Fakturatabelle ausgelesen und mit dem Systemdatum verglichen. Ist die Differenz zwischen diesen beiden Datum größer als ein Tag (> 1), dann wird der ReportServer-Job nicht ausgeführt. Sonst würde der Bericht mit demselben Inhalt des Vortages versandt werden und dies ist nicht erwünscht.
Dafür erstellen wir zuerst ein SSIS-Paket und definieren auf „Paketebene“ (Rechtsklick im Design-Bereich – Variable) eine Variable vom Typ „Integer“. Als Standardwert erhält die Variable „AgeLastData“ den Wert Null.
Innerhalb des SSIS-Paketes werden zwei Tasks angelegt:
In dem ersten Task „Letztes Rechnungsdatum prüfen“ wird anhand der folgenden SQL-Anweisung die Differenz zwischen dem letzten (Max) Rechnungstag und dem aktuellen Datenbank-Systemdatum ermittelt:
Select datediff(dd,MAX(Convert(smalldatetime,Rechnungsdatum)),GETDATE()) as AgeLastData from T_SAP_Fakturadaten
Wichtig ist, dass die SQL-Anweisung als Ergebnis nur eine Zeile zurückgibt. In unserem Beispiel wird die Spalte „AgeLastData“ genannt. Nun muss diese Spalte (aus dem Select-Statement) der oben angelegten Variable zugewiesen werden. Dies geschieht im Task-Editor (Doppelklick auf Task) in der Registerkarte „Resultset“:
Dadurch wird das SQL-Ergebnis (eine Zeile, ein Wert) in die Variable geschrieben.
Die Verbindung des SQL-Tasks mit dem nächsten, bedingt auszuführenden Schritt findet dann über den Variablenausdruck statt. Wie weiter oben zu sehen ist, handelt es sich bei dem Verbindungspfeil (blau) zwischen den beiden Tasks um eine spezielle, sogenannte „Ausdrucksverbindung“. Die Verbindung wird folgendermaßen bearbeitet:
Als Auswertungsvorgang wird der Standardwert „Einschränkung“ auf „Ausdruck“ geändert. Im Feld „Ausdruck“ benutzt man dann die zuvor angelegte Variable „@AgeLastData“ mit der Bedingung „<=1“. Das bedeutet, dass der nächste Schritt nur dann ausgeführt wird, wenn der Ausdruck erfüllt ist.
In unserem Beispiel werden im zweiten Task alle täglichen ReportServer-Jobs ausgeführt.
Wie bei der ersten Option muss man darauf achten, dass die Variablennamen „case sensitive“ sind und dass die Datentypen (Variablen vs. Code bzw. SQL) übereinstimmen müssen. Es ist keine implizite Konvertierung möglich.