Erstellen einer asynchronen Transformation mit der Skriptkomponente
Transformationskomponenten dienen im Datenfluss eines Integration Services-Pakets dazu, Daten auf dem Weg von der Quelle zum Ziel zu ändern und zu analysieren. Eine Transformation mit synchronen Ausgaben verarbeitet jede eingegebene Zeile, während sie die Komponente durchläuft. Eine Transformation mit asynchronen Ausgaben kann die Fertigstellung ihrer Verarbeitung abwarten, bis die Transformation alle Eingabezeilen empfangen hat; die Transformation kann bestimmte Zeilen auch ausgeben, bevor sie alle Eingabezeilen empfangen hat. In diesem Thema wird eine asynchrone Transformation erläutert. Wenn die Verarbeitung eine synchrone Transformation erfordert, finden Sie entsprechende Informationen unter Erstellen einer synchronen Transformation mit der Skriptkomponente. Weitere Informationen über die Unterschiede zwischen synchronen und asynchronen Komponenten finden Sie unter Grundlegendes zu synchronen und asynchronen Transformationen.
Eine Übersicht über die Skriptkomponente finden Sie unter Erweitern des Datenflusses mit der Skriptkomponente.
Die Skriptkomponente und der Infrastrukturcode, den sie generiert, erleichtern den Prozess der Entwicklung von benutzerdefinierten Datenflusskomponenten. Um die Funktionsweise der Skriptkomponente zu verstehen, kann es jedoch hilfreich sein, sich mit den Schritten im Entwickeln einer benutzerdefinierten Datenflusskomponente-Abschnitt vertraut zu machen, die Sie bei der Entwicklung einer benutzerdefinierten Datenflusskomponente befolgen müssen, und zwar insbesondere mit Entwickeln einer benutzerdefinierten Transformationskomponente mit synchronen Ausgaben.
Erste Schritte mit einer asynchronen Transformationskomponente
Wenn Sie auf der Registerkarte Datenfluss des SSIS-Designers eine Skriptkomponente hinzufügen, wird das Dialogfeld Skriptkomponententyp auswählen geöffnet, in dem Sie zur Vorkonfiguration der Komponente als Quelle, Transformation oder Ziel aufgefordert werden. Wählen Sie in diesem Dialogfeld die Option Transformation.
Konfigurieren einer asynchronen Transformationskomponente im Metadatenentwurfsmodus
Nachdem Sie die Option zur Erstellung einer Transformationskomponente ausgewählt haben, konfigurieren Sie die Komponente mit dem Transformations-Editor für Skripterstellung. Weitere Informationen finden Sie unter Konfigurieren der Skriptkomponente im Skriptkomponenten-Editor.
Um die Skriptsprache auszuwählen, die die Skriptkomponente verwenden wird, legen Sie die ScriptLanguage-Eigenschaft auf der Seite Skript im Dialogfeld Transformations-Editor für Skripterstellung fest.
Hinweis |
---|
Um die Standardskriptsprache für die Skriptkomponente festzulegen, verwenden Sie im Dialogfeld Optionen auf der Seite Allgemein die Option Skriptsprache. Weitere Informationen finden Sie unter Seite Allgemein. |
Eine Datenfluss-Transformationskomponente verfügt über eine Eingabe und unterstützt eine oder mehrere Ausgaben. Die Konfiguration der Eingaben und Ausgaben der Komponente ist einer der Schritte, die Sie mithilfe des Transformations-Editors für Skripterstellung im Metadatenentwurfsmodus ausführen müssen, bevor Sie das benutzerdefinierte Skript schreiben.
Konfigurieren von Eingabespalten
Eine mit der Skriptkomponente erstellte Transformationskomponente verfügt über eine einzelne Eingabe.
Die Spaltenliste auf der Seite Eingabespalten im Transformations-Editor für Skripterstellung zeigt die von der Ausgabe der Upstreamkomponente im Datenfluss verfügbaren Spalten. Markieren Sie die Spalten, die Sie transformieren oder durchlaufen möchten. Markieren Sie alle Spalten, die Sie an Ort und Stelle transformieren möchten, als Lesen/Schreiben.
Weitere Informationen über die Seite Eingabespalten im Transformations-Editor für Skripterstellung finden Sie unter Transformations-Editor für Skripterstellung (Seite Eingabespalten).
Konfigurieren von Eingaben, Ausgaben und Ausgabespalten
Eine Transformationskomponente unterstützt eine oder mehrere Ausgaben.
Häufig hat eine Transformation mit asynchronen Ausgaben zwei Ausgaben. Wenn Sie beispielsweise die Anzahl der Adressen in einer bestimmten Stadt zählen, sollten Sie die Adressdaten an einen Ausgang weitergeben, während Sie das Ergebnis der Aggregation an einen anderen Ausgang senden. Die Aggregationsausgabe erfordert auch eine neue Ausgabespalte.
Auf der Seite Eingaben und Ausgaben im Transformations-Editor für Skripterstellung sehen Sie, dass standardmäßig eine Ausgabe eingerichtet ist. Ausgabespalten sind hingegen nicht vorhanden. Auf dieser Seite des Editors können Sie die folgenden Elemente konfigurieren:
Sie haben die Möglichkeit, eine oder mehrere zusätzliche Ausgaben zu erstellen, beispielsweise eine Ausgabe für das Ergebnis einer Aggregation. Verwenden Sie die Schaltflächen Ausgabe hinzufügen und Ausgabe entfernen, um die Ausgaben der asynchronen Transformationskomponente zu verwalten. Legen Sie die SynchronousInputID-Eigenschaft jeder Ausgabe auf Null, um anzugeben, dass die Ausgabe nicht nur einfach Daten von einer Upstreamkomponente weitergibt oder sie an Ort und Stelle in den vorhandenen Zeilen und Spalten transformiert. Durch dies Einstellung werden die Ausgaben asynchron zur Eingabe.
Sie können der Eingabe und den Ausgaben einen beschreibenden Namen geben. In der Skriptkomponente werden diese Namen verwendet, um die typisierten Accessoreigenschaften zu erzeugen, mit denen Sie auf die Eingabe und Ausgaben in Ihrem Skript verweisen.
Häufig werden durch eine asynchrone Transformation dem Datenfluss Spalten hinzugefügt. Wenn die SynchronousInputID-Eigenschaft einer Ausgabe Null beträgt, was angibt, dass die Ausgabe nicht nur einfach Daten von einer Upstreamkomponente weitergibt oder sie an Ort und Stelle in den vorhandenen Zeilen und Spalten transformiert, müssen Sie in der Ausgabe explizit Ausgabespalten hinzufügen und diese konfigurieren. Ausgabespalten haben nicht dieselben Namen wie die Eingabespalten, denen sie zugeordnet sind.
Sie können weitere Spalten hinzufügen, um zusätzliche Informationen aufzunehmen. Sie müssen einen eigenen Code schreiben, um die zusätzlichen Spalten mit Daten aufzufüllen. Informationen über das Reproduzieren des Verhaltens einer Standardfehlerausgabe finden Sie unter Simulieren einer Fehlerausgabe für die Skriptkomponente.
Weitere Informationen über die Seite Eingaben und Ausgaben des Transformations-Editors für Skripterstellung finden Sie unter Transformations-Editor für Skripterstellung (Seiten Eingaben und Ausgaben).
Hinzufügen von Variablen
Wenn Sie die Werte vorhandener Variablen in Ihrem Skript verwenden möchten, können Sie diese in den Eigenschaftenfeldern für ReadOnlyVariables und ReadWriteVariables auf der Seite Skript des Transformations-Editors für Skripterstellung hinzufügen.
Wenn Sie mehrere Variablen in die Eigenschaftsfelder hinzufügen, trennen Sie die Variablennamen durch Kommas. Sie können auch mehrere Variablen auswählen, indem Sie auf die Schaltfläche mit den Auslassungszeichen (…) neben den Eigenschaftsfeldern für ReadOnlyVariables und ReadWriteVariables klicken und dann die Variablen im Dialogfeld Variablen auswählen festlegen.
Allgemeine Informationen über das Verwenden von Variablen mit der Skriptkomponente finden Sie unter Verwenden von Variablen in der Skriptkomponente.
Weitere Informationen über die Seite Skript des Transformations-Editors für Skripterstellung finden Sie unter Transformations-Editor für Skripterstellung (Seite Skript).
Skripterstellung für eine asynchrone Transformationskomponente im Codeentwurfsmodus
Nachdem Sie alle Metadaten für Ihre Komponente konfiguriert haben, können Sie das benutzerdefinierte Skript schreiben. Klicken Sie auf der Seite Skript im Transformations-Editor für Skripterstellung auf Skript bearbeiten, um die Microsoft Visual Studio Tools for Applications (VSTA)-IDE zu öffnen und Ihr benutzerdefiniertes Skript hinzuzufügen. Die von Ihnen verwendete Skriptsprache hängt davon ab, ob Sie auf der Seite SkriptMicrosoft Visual Basic 2008 oder Microsoft Visual C# 2008 als Skriptsprache für die ScriptLanguage-Eigenschaft festgelegt haben.
Wichtige Informationen, die alle Arten von Komponenten betreffen, die mithilfe der Skriptkomponente erstellt wurden, finden Sie unter Codieren und Debuggen der Skriptkomponente.
Grundlegendes zum automatisch generierten Code
Wenn Sie nach der Erstellung und Konfiguration einer Transformationskomponente die VSTA IDE öffnen, wird die bearbeitbare ScriptMain-Klasse im Code-Editor mit Stubs für die ProcessInputRow- und CreateNewOutputRows-Methode angezeigt. In der ScriptMain-Klasse schreiben Sie Ihren benutzerdefinierten Code, und ProcessInputRow ist die wichtigste Methode in einer Transformationskomponente. Die CreateNewOutputRows-Methode wird eher in einer Quellkomponente verwendet, die insofern wie eine asynchrone Transformation funktioniert, dass beide Komponenten eigene Ausgabezeilen erstellen müssen.
Wenn Sie das VSTA-Fenster Projektexplorer öffnen, können Sie sehen, dass die Skriptkomponente auch schreibgeschützte BufferWrapper- und ComponentWrapper-Projektelemente generiert hat. Die ScriptMain-Klasse erbt von der UserComponent-Klasse im ComponentWrapper-Projektelement.
Zur Laufzeit ruft das Datenflussmodul die PrimeOutput-Methode der UserComponent-Klasse auf, die die PrimeOutput-Methode der übergeordneten ScriptComponent-Klasse überschreibt. Die PrimeOutput-Methode ruft ihrerseits die CreateNewOutputRows-Methode auf.
Als nächstes ruft das Datenflussmodul die ProcessInput-Methode der UserComponent-Klasse auf, die die ProcessInput-Methode der übergeordneten ScriptComponent-Klasse überschreibt. Die ProcessInput-Methode durchläuft der Reihe nach in Schleifen die Zeilen im Eingabepuffer und ruft für jede Zeile einmal die ProcessInputRow-Methode auf.
Schreiben von benutzerdefiniertem Code
Um die Erstellung einer benutzerdefinierten asynchronen Transformationskomponente abzuschließen, müssen Sie mit der überschriebenen ProcessInputRow-methode die Daten in jeder Zeile des Eingabepuffers verarbeiten. Weil die Ausgaben nicht mit der Eingabe synchron sind, müssen Sie Datenzeilen explizit in die Ausgaben schreiben.
Bei einer asynchronen Transformation können Sie mit der AddRow-methode der Ausgabe Zeilen hinzufügen, und zwar je nachdem, entweder aus der ProcessInputRow-Methode oder der ProcessInput-methode heraus. Sie brauchen die CreateNewOutputRows-Methode nicht zu verwenden. Wenn Sie eine einzelne Ergebniszeile, wie zum Beispiel Aggregationsergebnisse, in eine bestimmte Ausgabe schreiben, können Sie die Ausgabezeile vorher mithilfe der CreateNewOutputRows-Methode erstellen und ihre Werte später nach Verarbeitung aller Eingabezeilen auffüllen. Es ist jedoch nicht sinnvoll, in der CreateNewOutputRows-Methode mehrere Zeilen zu erstellen, weil Sie mit der Skriptkomponente nur die aktuelle Zeile in einer Eingabe oder Ausgabe verwenden können. Die CreateNewOutputRows-Methode ist wichtiger bei einer Quellkomponente, wo keine Eingabezeilen zu verarbeiten sind.
Sie können auch die ProcessInput-Methode an sich überschreiben, so dass Sie zusätzliche vorbereitende oder abschließende Verarbeitungsvorgänge ausführen können, bevor oder nachdem Sie den Eingabepuffer durchlaufen und ProcessInputRow für jede Zeile aufrufen. Beispielsweise wird in einem der Codebeispiele in diesem Thema ProcessInput überschrieben, um die Anzahl der Adressen in einer bestimmten Stadt zu zählen, während ProcessInputRow Zeilen durchläuft. In dem Beispiel wird der Zusammenfassungswert in die zweite Ausgabe geschrieben, nachdem alle Zeilen verarbeitet wurden. In dem Beispiel wird die Ausgabe in ProcessInput abgeschlossen, weil die Ausgabepuffer nicht mehr verfügbar sind, wenn PostExecute aufgerufen wird.
Je nach Ihren Anforderungen können Sie auch Skript in den PreExecute- und PostExecute-Methoden schreiben, die in der ScriptMain-Klasse verfügbar sind, um vorbereitende oder abschließende Verarbeitungsvorgänge auszuführen.
Hinweis |
---|
Wenn Sie eine benutzerdefinierte Datenflusskomponente von Grund auf erstellen würden, wäre es wichtig, die PrimeOutput-Methode zu überschreiben, um Verweise auf die Ausgabepuffer zwischenzuspeichern, damit Sie später den Puffern Datenzeilen hinzufügen können. In der Skriptkomponenten ist das nicht notwendig, weil eine automatisch erzeugte Klasse jeden Ausgabepuffer im BufferWrapper-Projektelement erstellt. |
Beispiel
In diesem Beispiel wird der benutzerdefinierte Code veranschaulicht, der in der ScriptMain-Klasse zur Erstellung einer asynchronen Transformationskomponente erforderlich ist.
Hinweis |
---|
In diesen Beispielen werden die erste und vierte Spalte der Person.Address-Tabelle in der AdventureWorks2008R2-Datenbank, nämlich die Spalten int AddressID und nvarchar(30) City, durch den Datenfluss weitergeleitet. Die gleichen Daten werden in den Quellen-, Transformations- und Zielbeispielen in diesem Abschnitt verwendet. Zusätzliche Voraussetzungen und Annahmen werden für jedes Beispiel dokumentiert. |
Dieses Beispiel zeigt eine asynchrone Transformationskomponente mit zwei Ausgaben. Bei dieser Transformation werden die Spalten AddressID und City an eine Ausgabe übergeben; gleichzeitig wird die Anzahl der Adressen in einer bestimmten Stadt (Redmond, Washington, USA) gezählt, und der resultierende Wert wird an eine zweite Ausgabe ausgegeben.
Wenn Sie diesen Beispielcode ausführen möchten, müssen Sie das Paket und die Komponente folgendermaßen konfigurieren:
Fügen Sie der Datenfluss-Designeroberfläche eine neue Skriptkomponente hinzu, und konfigurieren Sie sie als Transformation.
Verbinden Sie die Ausgabe einer Quelle einer anderen Transformation mit der neuen Transformation im Designer. Diese Ausgabe sollte Daten aus der Person.Address-Tabelle der AdventureWorks2008R2-Beispieldatenbank bereitstellen, die mindestens die Spalten AddressID und City enthält.
Öffnen Sie den Transformations-Editor für Skripterstellung. Wählen Sie auf der Seite Eingabespalten die Spalten AddressID und City aus.
Fügen Sie auf der Seite Eingaben und Ausgaben die Ausgabespalten AddressID und City hinzu, und konfigurieren Sie sie auf die erste Ausgabe. Fügen Sie eine zweite Ausgabe hinzu, und fügen Sie eine Ausgabespalte für den Zusammenfassungswert in der zweiten Ausgabe hinzu. Setzen Sie die SynchronousInputID-Eigenschaft der ersten Ausgabe auf 0, weil in diesem Beispiel jede Eingabezeile explizit in die erste Ausgabe kopiert wird. Die SynchronousInputID-Eigenschaft der neu erstellten Ausgabe ist bereits auf 0 gesetzt.
Benennen Sie die Eingabe, die Ausgaben und die neue Ausgabespalte um, um ihnen beschreibendere Namen zu geben. In dem Beispiel wird MeineAdresseingabe als Name der Eingabe, MeineAdressausgabe und MeineZusammenfassungsausgabe für die Ausgaben und MeineRedmond-Anzahl für die Ausgabespalte in der zweiten Ausgabe verwendet.
Klicken Sie auf der Seite Skript auf Skript bearbeiten, und geben Sie das folgende Skript ein. Schließen Sie anschließend die Skriptentwicklungsumgebung und den Transformations-Editor für Skripterstellung.
Erstellen und konfigurieren Sie eine Zielkomponente für die erste Ausgabe, die die Spalten AddressID und City erwartet, z. B. ein SQL Server-Ziel, oder die Beispielzielkomponente, die unter Erstellen eines Ziels mit der Skriptkomponente veranschaulicht wird. Verbinden Sie anschließend die erste Ausgabe der Transformation, MeineAdressausgabe, mit der Zielkomponente. Sie können eine Zieltabelle erstellen, indem Sie den folgenden Transact-SQL-Befehl in der AdventureWorks2008R2-Datenbank ausführen:
CREATE TABLE [Person].[Address2]( [AddressID] [int] NOT NULL, [City] [nvarchar](30) NOT NULL )
Erstellen Sie eine weitere Zielkomponente für die zweite Ausgabe, und konfigurieren Sie sie. Verbinden Sie dann die zweite Ausgabe der Transformation, MeineZusammenfassungsausgabe, mit der Zielkomponente. Da in der zweiten Ausgabe eine einzelne Zeile mit nur einem Wert geschrieben wird, können Sie mit einem Verbindungs-Manager für Flatfiles, der eine Verbindung zu einer neuen Datei mit einer Spalte herstellt, einfach ein Ziel konfigurieren. Im Beispiel wird diese Zielspalte MeineRedmond-Anzahl genannt.
Führen Sie das Beispiel aus.
Public Class ScriptMain
Inherits UserComponent
Private myRedmondAddressCount As Integer
Public Overrides Sub CreateNewOutputRows()
MySummaryOutputBuffer.AddRow()
End Sub
Public Overrides Sub MyAddressInput_ProcessInput(ByVal Buffer As MyAddressInputBuffer)
While Buffer.NextRow()
MyAddressInput_ProcessInputRow(Buffer)
End While
If Buffer.EndOfRowset Then
MyAddressOutputBuffer.SetEndOfRowset()
MySummaryOutputBuffer.MyRedmondCount = myRedmondAddressCount
MySummaryOutputBuffer.SetEndOfRowset()
End If
End Sub
Public Overrides Sub MyAddressInput_ProcessInputRow(ByVal Row As MyAddressInputBuffer)
With MyAddressOutputBuffer
.AddRow()
.AddressID = Row.AddressID
.City = Row.City
End With
If Row.City.ToUpper = "REDMOND" Then
myRedmondAddressCount += 1
End If
End Sub
End Class
public class ScriptMain:
UserComponent
{
private int myRedmondAddressCount;
public override void CreateNewOutputRows()
{
MySummaryOutputBuffer.AddRow();
}
public override void MyAddressInput_ProcessInput(MyAddressInputBuffer Buffer)
{
while (Buffer.NextRow())
{
MyAddressInput_ProcessInputRow(Buffer);
}
if (Buffer.EndOfRowset())
{
MyAddressOutputBuffer.SetEndOfRowset();
MySummaryOutputBuffer.MyRedmondCount = myRedmondAddressCount;
MySummaryOutputBuffer.SetEndOfRowset();
}
}
public override void MyAddressInput_ProcessInputRow(MyAddressInputBuffer Row)
{
{
MyAddressOutputBuffer.AddRow();
MyAddressOutputBuffer.AddressID = Row.AddressID;
MyAddressOutputBuffer.City = Row.City;
}
if (Row.City.ToUpper() == "REDMOND")
{
myRedmondAddressCount += 1;
}
}
}
|