Workaround: Error Propagation in SSIS Parent-Child-Paketen

In meinem letzten Projekt hatte ich die Aufgabe Fehlerlogging im Eventhandler umzusetzen, wobei ich im Execute Package Task (EPT) auf ein Problem gestoßen bin. Bei einem Fehler im Child-Package wurden die OnError-Events im Child-Package , sowie im EPT ausgeführt. Das führte dann zu doppelten Einträgen in meiner Logging-Tabelle.

 

Im MSDN gibt es folgende Anmerkung zu dieser Variable

.

clip_image001Note

The value of the Propagate variable is disregarded during the validation of the package. If you set Propagate to False in a child package, this does not prevent an event from propagating up to the parent package. To prevent the parent package from handling the event, set the DisableEventHandlers property of the Execute Package task to True.

 

Auch nach dem umstellen der Systemvariable Propagate auf False wurde das Problem nicht behoben, wodurch ich mir die hier dargestellte Lösung überlegt habe. Wird in SSIS ein Event ausgelöst kann im EventHandler auch immer die ID des fehlerhaften Tasks ermittelt werden. Daher müssen die IDs des EPT und die des fehlgeschlagenen Tasks gleich sein. Wie das geschehen kann, möchte ich an dem nachfolgenden Beispiel deutlich machen.

 

clip_image003

 

Zu Beginn werden die zwei SSIS Pakete Parent und Child benötigt. Um einen Fehler im Child-Package zu simulieren habe ich dort einen ScriptTask mit folgendem Code angelegt.

 

Dts.TaskResult = (int)ScriptResults.Failure;

 

In folgenden Tasks muss im OnError-Eventhandler die Variable Propagate auf Flase gesetzt werden.

  • EPT
  • SkriptTask

clip_image004
 
Im Parent-Package werden zwei Variablen benötigt. Eine zur Zwischenspeicherung der ID des EPT und eine boolsche Variable, die angibt, ob der Fehler nicht vom Child-Package stammt.

 

clip_image005

 

Dabei stellt sich nun die Frage, wie man zuverlässig an die ID des EPT herankommt? Durch einen Event, der nur vom EPT selbst ausgelöst werden kann. Ich habe mich für den OnPreExecution Event entschieden, da dieser immer vor dem OnError Event ausgelöst wird. Dort habe ich einen ScriptTask angelegt, der die NoChildError-Variable wieder auf True setzt und dann den Wert der SourceID an die EPT_ID Variable übergibt.

 

Dts.Variables[„NotChildError“].Value = true;

Dts.Variables[„EPT_ID“].Value = Dts.Variables[„SourceID“].Value;

 

Die Unterscheidung der Fehlerquelle passiert im OnError-Event.

 

clip_image006

 

Wird das Event ausgelöst, überprüft dort der ScriptTask “ST check SourceID” ob sich die EPT_ID und die SourceID voneinander unterscheiden. Wenn das der Fall ist, wird die NotChildError Variable auf False gesetzt.

 

string EPT_ID = (string)Dts.Variables[„EPT_ID“].Value;

string SourceID = (string)Dts.Variables[„SourceID“].Value;

if(!EPT_ID.Equals(SourceID))

{

Dts.Variables[„NotChildError“].Value = false;

}

 

In der Rangfolgeneinschränkung muss nun der Ausdruck NotChildError geprüft werden. Ist der Wert True wird der nächste Task (Logging) ausgefüht, bei False natürlich nicht.

 

clip_image008

 

In diesem Blogbeitrag wurde gezeigt wie das Fehlerlogging von Parent- bis hin zum Child-Package in SSIS umgesetzt werden kann. Dieses „Problem“ des Weiterreichens von Fehlern liegt bei den SQL-Servern 2005 bis 2012 vor.

Schreibe einen Kommentar