Wenn man größere SSIS-Jobs schreibt, sollten diese Jobs später auf ihre Laufzeiten kontrolliert werden. Läuft die Laufzeit eines SSIS-Jobs aus dem Ruder, ist es sinnvoll, protokolliert zu haben, wie lange welcher Task des SSIS-Jobs läuft, um schnell den Schuldigen ausfindig zu machen. Alternative Techniken wie Analyse des Log-Files sind sehr mühselig.
In dem Code-Beispiel gehen wir davon aus, dass es eine SQL-Tabelle gibt, in der für jeden SSIS-Job ein Eintrag erzeugt wird, so dass es eine eindeutige Lauf-ID gibt. Diese Lauf-ID wird im ersten Schritt des SSIS-Jobs erzeugt. Dies ist bei uns “Best Practice”
Zur Protokollierung legen wir eine Tabelle wie folgt an:
CREATE TABLE [dbo].[META_ImportLaufTaskDauer](
[ImportLauf_ID] [int] NOT NULL,
[TaskName] [nvarchar](200) NOT NULL,
[Startzeitpunkt] [datetime] NOT NULL,
[Endezeitpunkt] [datetime] NULL,
CONSTRAINT [PK_META_ImportLaufTaskDauer] PRIMARY KEY CLUSTERED
(
[ImportLauf_ID] ASC,
[TaskName] ASC
)
)
Die Spaltennamen sollten selbst erklärend sein.
In diese Tabelle wird nun über Events im SSIS-Paket geschrieben. Dazu werden auf der obersten Ebene des Pakets (und nur dort – also nicht etwa für jede Task) die Events für OnPreExecute und OnPostExecute angelegt:
In dem OnPreExecute wird nun der Startzeitpunkt der Task in die Tabelle geschrieben… :
Dazu wird ein Execute SQL-Task angelegt. Dieser beinhaltet folgendes SQL:
declare @Laufid int
set @Laufid = ?if @LaufId > 0
INSERT INTO META_ImportLaufTaskDauer (ImportLauf_ID, TaskName, Startzeitpunkt)
VALUES
(@laufid, left(?, 200), getdate())
Das Mapping der Variablen sieht so aus:
Die ID des Importlaufs findet sich hier in der Benutzer-Variablen LaufID. Die andere Variable ist eine System-Variable, die uns den verantwortlichen Task nennt.
… und im OnPostExecute der Endzeitpunkt der Task mit folgendem SQL:
declare @Laufid int
set @Laufid = ?if @LaufId > 0
UPDATE META_ImportLaufTaskDauer
Set Endezeitpunkt = getdate()
where ImportLauf_ID = @Laufid and TaskName= left(?, 200)
Das ParameterMapping ist wie im OnPreExecute.
In dem Fall, dass das ETL Schleifen beinhaltet, funktioniert obige Lösung nicht:
Der Primärschlüssel der Tabelle META_ImportLaufTaskDauer lässt einen TaskNamen nur einmal zu. Deswegen muss der Primärschlüssel geändert werden (am besten auf eine neue Spalte, die eine Identity ist)
Im PostExecute ergänzt man dann die WHERE-Clause des Update-Statements noch um AND EndeZeitpunkt IS NULL (damit immer der aktuelle Durchlauf der Schleife den Endezeitpunkt gesetzt bekommt)