Category: "Integration Services"

Dieser Blog ist umgezogen // This Blog has moved: http://andreas-wolter.com/blog/

http://andreas-wolter.com/blog/

Liebe Leser
dieser Blog ist hiermit nur noch „Archiv“ und wird nicht mehr weiter gepflegt.
Seit August 2017 finden sich neue Artikel ausschließlich unter der neuen URL:
http://andreas-wolter.com/blog/

Dear Readers
this blog is now merely an „archive“ and no longer being updated.
Since August 2017 new articles are exclusively available under the new URL:
http://andreas-wolter.com/en/blog/

Die aufwändige Mehrsprachigkeit (Deutsch und Englisch professionell manuell übersetzt) wird beibehalten – aber Layout-technisch anders gelöst. Damit dürfte ich immer noch den einzigen mehrsprachigen IT-Blog weltweit betreiben.
Ich hoffe, das neue Design gefällt Ihnen.

The complex multilingualism (German and English professionally manually translated) is being continued – but solved differently in terms of layout. With that I most likely still operate the only multilingual IT-Blog worldwide.
I hope you like the new design.

 

 

Mein aktueller Artikel, der erstmalig ausschließlich auf der neuen Website zu finden ist, lautet: Optimieren von Workflows mit In-Memory und nativ kompilierten Objekten - oder wie es nicht funktioniert

My currently last article, which is exclusively available at the new website for the first time, is Optimizing workflows with In-Memory and Natively Compiled Objects - or how it does not work

 

Cu at my new Blog

Andreas

Integration Services: Looping & “continue on error”

Eine häufige Aufgabe bei der Arbeit mit Integration Services Paketen ist es, eine Routine in einer Schleife auszuführen.

Nehmen wir den konkreten Fall: ein For Each-Loop zum rekursiven Auslesen von Textdateien aus einer Verzeichnisstruktur und Verschieben an einen Zielort.

Wenn die Operation aufgrund von einer geöffneten Datei (z.B. der Log-Writer Prozess) fehlschlägt, schlägt damit der Task “Move file” fehl. Sodann der Container “For Each Loop”, und dann das gesamte Paket. Das ist das Standardverhalten: das Event “Error” wird propagiert.

Das sieht in etwa so aus (hier mit einen For Loop):

SSIS_EventPropagation_standard

Man sieht trotz der versuchten “Fehlerbehandlung” in dem Script-Task “SCR-Fail” schlägt der Container fehl.

Das ist in diesem Fall aber nicht unbedingt das gewünschte Ergebnis.
Man möchte, das die Operation einfach mit der nächsten Datei fortfährt und eventuell liegengebliebene Dateien in einem späteren Durchlauf einfach holen.

Dafür muss man das propagieren des Fehlers auf Container-Ebene unterbinden. Die dafür extra vorhandene Systemvariable “Propagate” ist ausnahmsweise deswegen auch manuell änderbar. Allerdings gibt es diese nur in den Event Handlern.

Das heisst für den fehlschlagenen SQL-Task in diesem Beispiel ist ein EventHandler für “OnError” anzulegen. Dort findet man dann die besagte Variable und schaltet sie auf False

SSIS_EventPropagation_SystemVariablePropagate 

 

Das würde an sich schon genügen, um das Paket einfach weiterlaufen zu lassen.

Allerdings ist es in der Regel wünschenswert, im Anschluss eine bedingte Reaktion auf das erfolgreiche oder erfolglose Verschieben der Datei erfolgen zu lassen. In diesem Beispiel ein T-SQL-Schritt bei Erfolg, und der Script-Task “Fail” bei Misserfolg.

Da nun kein Fehler mehr propagiert wird, ist ein kleiner Kunstgriff vonnöten: Man definiert sich eine Variable, welche im Fehlerfall einen anderen Wert erhält und liest diese dann bei dem Precedence-Constraint zusätzlich mit aus.

Am einfachsten geht das mit dem im Fehlerfall ohnehin vorhandenen ErrorCode – innerhalb des EventHandler natürlich.

Dort leitet man den Wert der Systemvariable “ErrorCode” einfach in seine eigens zuvor angelegte User-Variable um:

Dts.Variables("User::ErrorCode").Value = Dts.Variables("System::ErrorCode").Value

Im ControlFlow wird dann ein “OnCompletion” – Precedence Constraint verwendet, und zusätzlich die Variable in der Expression "@[User::ErrorCode] != 0" ausgewertet

Das gewünschte Ergebnis verhält sich dann so:

SSIS_EventPropagation_Result

Der Fehler im Task wird abgehandelt, und die Arbeit wird fortgesetzt.

 

happy coding :)

 

Andreas Wolter

 

Sarpedon Quality Lab