{"id":331,"date":"2015-06-14T13:17:04","date_gmt":"2015-06-14T12:17:04","guid":{"rendered":"http:\/\/www.csopro.de\/biblog\/?p=331"},"modified":"2015-06-14T18:20:10","modified_gmt":"2015-06-14T17:20:10","slug":"quarantne-teil-2-schleife-ber-alle-komponenten-eines-data-flows-und-untersuchung-bestehender-fehlerbehandlung","status":"publish","type":"post","link":"https:\/\/www.csopro.de\/biblog\/2015\/06\/quarantne-teil-2-schleife-ber-alle-komponenten-eines-data-flows-und-untersuchung-bestehender-fehlerbehandlung\/","title":{"rendered":"Quarant&auml;ne-Teil 2: Schleife &uuml;ber alle Komponenten eines Data Flows und Untersuchung bestehender Fehlerbehandlung"},"content":{"rendered":"<p align=\"left\">In dem letzten Blog-Eintrag hatten wir eine Schleife um alle Data Flows erstellt und eine Data Flow identifizieren k\u00f6nnen.<\/p>\n<p align=\"left\">Heute wollen wir eine Schleife \u00fcber alle Komponenten bauen und die Komponenten etwas genauer analysieren, insbesondere auf vorhandene Fehlerbehandlung.<\/p>\n<p align=\"left\">Im letzten Kapitel hatte wir eine Methode <em>processAllExecutables<\/em> geschrieben. Diese enthielt in einer Schleife ein <em>Executable<\/em> mit Variablennamen <em>e<\/em>.<\/p>\n<p align=\"left\">\u00dcber<\/p>\n<blockquote>\n<p align=\"left\">If TypeOf e Is TaskHost Then<span style=\"color: #2b2b2b; font-size: medium;\"> \u2026<\/span><\/p>\n<\/blockquote>\n<p align=\"left\">hatten wir ermittelt, dass es sich um einen Data Flow handelt.<\/p>\n<h1 align=\"left\">Schleife \u00fcber alle Komponenten<\/h1>\n<h1><\/h1>\n<p align=\"left\">Nun erstellen wir uns zun\u00e4chst ein paar Variablen:<\/p>\n<blockquote><p>Dim th As TaskHost<br \/>\nth = CType(e, TaskHost)<br \/>\nDim name As String<br \/>\nname = CType(e, TaskHost).Name<\/p>\n<p>If TypeOf th.InnerObject Is<br \/>\nMicrosoft.SqlServer.Dts.Pipeline.Wrapper.MainPipe Then<br \/>\nDim pipe As MainPipe = CType(th.InnerObject, MainPipe)<br \/>\n\u2026<br \/>\nEnd If<\/p><\/blockquote>\n<p><span style=\"color: #767676;\">Diese bedeuten:<\/span><\/p>\n<ul>\n<li><span style=\"color: #767676;\">den Namen des Data Flows in <em>name<\/em><\/span><\/li>\n<li><span style=\"color: #767676;\">In <em>th<\/em> steht der TaskHost, also Data Flow<\/span><\/li>\n<li><span style=\"color: #767676;\">Der <em>th<\/em> hat ein inneres Objekt, die sogenannte Main Pipe. Diese beinhaltet weiterhin alle Data Flow-Komponente. An ihr sind wir also im besonderen interessiert. Wir haben sie in der Variablen <em>pipe <\/em>gespeichert.<\/span><\/li>\n<\/ul>\n<p><span style=\"color: #767676;\">Nun ist es ganz einfach alle Komponenten eines Data Flows zu durchlaufen, da sie in der Collection <em>ComponentMetaDataCollection<\/em> des <em>MainPipe<\/em>-Objekts enthalten sind:<\/span><\/p>\n<blockquote><p><span style=\"color: #767676;\">For Each comp As IDTSComponentMetaData100 In pipe.ComponentMetaDataCollection<br \/>\n\u2026<br \/>\nNext comp<\/span><\/p><\/blockquote>\n<h1><\/h1>\n<h1>Identifikation des bestehenden Error Handlings<\/h1>\n<p>Als erste wollen wir wissen, ob diese Komponente \u00fcberhaupt grunds\u00e4tzlich \u00fcber ein Error Handling verf\u00fcgen kann. \u00dcberraschender Weise gibt es n\u00e4mlich Komponenten, an die man kein Error Handling anschlie\u00dfen kann, z.B. MultiCast, Union all, aber auch eine Skript-Komponente, die ja definitiv einen Fehler erzeugen kann.<\/p>\n<p>Wie erkennen wir nun, ob eine Komponente ein Error Handling zul\u00e4sst?<\/p>\n<p>Jede Komponente hat eine Input- und eine <em>OutputCollection<\/em>. Diese sieht man auch in SSIS im erweiterten Editor, so z.B. bei einer Derived Column:<\/p>\n<p><a href=\"https:\/\/www.csopro.de\/biblog\/wp-content\/uploads\/2015\/06\/image.png\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border: 0px;\" title=\"image\" src=\"https:\/\/www.csopro.de\/biblog\/wp-content\/uploads\/2015\/06\/image_thumb.png\" alt=\"image\" width=\"514\" height=\"482\" border=\"0\" \/><\/a><\/p>\n<p>Auf der linken Seite sehen wir 3 Ports dieser Komponente. Davon finden sich im Objekt-Modell der erste in der <em>InputCollection<\/em> und die anderen beiden in der <em>OutputCollection<\/em>. Der Fehler-Output unterscheidet sich nun von anderen Outputs dadurch, dass die Property <em>IsErrorOut <\/em>auf <em>true<\/em> gesetzt ist.<\/p>\n<p>Wenn wir nun die OutputCollection durchlaufen, k\u00f6nnen wir den Error Output ermitteln bzw. erkennen, dass diese Komponente gar keinen Error Output erm\u00f6glicht.<\/p>\n<p>Wichtig! Wie in der SSIS-Oberfl\u00e4che auch, sind diese Outputs sichtbar unabh\u00e4ngig davon, ob sie nachher mit Pfaden zu einer anderen Komponente verkn\u00fcpft sind. Wenn also ein Error Output nicht im Objektmodell vorhanden ist, hei\u00dft das, dass keine Fehlerbehandlung f\u00fcr dieses Komponente m\u00f6glich ist, nicht etwa, dass nur noch keine definiert worden ist.<\/p>\n<p>Was uns jetzt noch interessiert ist, ob f\u00fcr diese Komponente, wenn sie einen Error Output hat, dieser bereits verwendet wird. Das ist dann der Fall, wenn es einen Pfad gibt, der den Error Output als Beginn des Pfades hat. Programmatisch bedeutet das, dass wir die <em>PathCollection<\/em> durchlaufen m\u00fcssen und alle Anfangspunkte des Pfades mit dem <em>IdentificationString<\/em> des Error Outputs vergleichen m\u00fcssen.<\/p>\n<p>Ich habe das so implementiert:<\/p>\n<blockquote><p>&#8218;ermittle Error Output<br \/>\nDim hatErrorOutput As Boolean = False<br \/>\nDim nrOfErrorOutput As Byte = 0<br \/>\nDim ErrorOutputSchonVerwendet As Boolean = False<\/p>\n<p>For outpNr As Integer = 0 To comp.OutputCollection.Count &#8211; 1<br \/>\n&#8218;Ist das ein Error Output?<br \/>\nIf comp.OutputCollection(outpNr).IsErrorOut Then<br \/>\n&#8218;ja!<br \/>\nhatErrorOutput = True<br \/>\nnrOfErrorOutput = outpNr<br \/>\n&#8218;wird dieser Error Output schon in einem Pfad benutzt?<br \/>\n&#8217;schaue nach in pipe.PathCollection<br \/>\nDim id As String<br \/>\nid = comp.OutputCollection.Item(outpNr).IdentificationString<br \/>\nFor p As Integer = 0 To pipe.PathCollection.Count &#8211; 1<br \/>\nIf pipe.PathCollection(p).StartPoint.IdentificationString = id Then<br \/>\nErrorOutputSchonVerwendet = True<br \/>\nEnd If<br \/>\nNext p<br \/>\nEnd If<br \/>\nNext outpNr<\/p><\/blockquote>\n<p>Somit wissen wir<\/p>\n<ul>\n<li>ob die Komponente ein Error Handling erlaubt (<em>hatErrorOutput<\/em>)<\/li>\n<li>ob f\u00fcr diese Komponente ein Error Handling bereits definiert ist (<em>ErrorOutputSchonVerwendet<\/em>). Diesen Fall soll unser Quarant\u00e4ne-Algorithmus n\u00e4mlich ignorieren (Da hat sich der Entwickler des Pakets ja was dabei gedacht)<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>In dem letzten Blog-Eintrag hatten wir eine Schleife um alle Data Flows erstellt und eine Data Flow identifizieren k\u00f6nnen. Heute wollen wir eine Schleife \u00fcber alle Komponenten bauen und die Komponenten etwas genauer analysieren, insbesondere auf vorhandene Fehlerbehandlung. Im letzten Kapitel hatte wir eine Methode processAllExecutables geschrieben. Diese enthielt in einer Schleife ein Executable mit &hellip; <a href=\"https:\/\/www.csopro.de\/biblog\/2015\/06\/quarantne-teil-2-schleife-ber-alle-komponenten-eines-data-flows-und-untersuchung-bestehender-fehlerbehandlung\/\" class=\"more-link\"><span class=\"screen-reader-text\">Quarant&auml;ne-Teil 2: Schleife &uuml;ber alle Komponenten eines Data Flows und Untersuchung bestehender Fehlerbehandlung<\/span> weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10,5,38],"tags":[27,18,19],"class_list":["post-331","post","type-post","status-publish","format-standard","hentry","category-integrationservices","category-projekte","category-visualbasicdotnet","tag-data-flow","tag-error-handling","tag-quarantaene"],"_links":{"self":[{"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/posts\/331","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/comments?post=331"}],"version-history":[{"count":4,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/posts\/331\/revisions"}],"predecessor-version":[{"id":337,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/posts\/331\/revisions\/337"}],"wp:attachment":[{"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/media?parent=331"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/categories?post=331"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/tags?post=331"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}