0

フラット ファイルからカスタム コンポーネントへのマッピングを実行時に決定できるようにすることで、高いレベルの柔軟性を実現することを目的としたパッケージを作成しました。私は次のようにしてそうしました:

  1. データベース テーブルから列マッピングを取得するパッケージを作成しました。このテーブルには、「フラット ファイル ソース列」と「データベース テーブル列」が含まれます。このデータはパッケージ変数に格納されます。

  2. フラット ファイルの行を処理し、フラット ファイルのデータをデータ テーブルに入力して「データベース テーブルの列」にするカスタム パイプライン コンポーネント (宛先アダプター) を作成しました。このデータ テーブルは変数に格納されます。(このカスタム コンポーネントは、デザイナーを通じてパッケージに追加されませんでした)

  3. 「動的マッピング」を実現するために、列マッピングをフェッチする最初の SQL クエリの後に実行されるスクリプト タスクを作成しました。スクリプト タスクは次のことを行います。

    • パッケージを作成します
    • データ フロー タスクを追加します
    • データ フロー タスクにフラット ファイル ソース (および接続) を追加します。
    • カスタム コンポーネントを追加します
    • フラット ファイル ソースをカスタム コンポーネントにマップする
    • 「親パッケージ変数」を渡し、パッケージを実行します
    • 新しく作成されたパッケージから「データ テーブル変数」を取得します

次に、データ テーブル変数の各レコードに対して挿入ステートメントを実行する別のスクリプト タスクを実行します。

私が抱えている問題は、プログラムで作成したパッケージにフラット ファイルの宛先を追加しない限り、パッケージが実行されないことです。

プログラムで作成したパッケージを保存し、デザイナーを使用してフラット ファイルの保存先を追加することで、これを発見しました。次に、スクリプト タスクを開き、このパッケージをロードして実行すると、実行されました。

以下は、子パッケージをプログラムで作成するためのコードです。

 Try
  'CREATE PACKAGE
  package = New Microsoft.SqlServer.Dts.Runtime.Package()

  '-----------------------
  'CREATE DATA FLOW TASK
  '-----------------------
  Dim PipelineTask As Executable = package.Executables.Add("STOCK:PipelineTask")
  Dim DataFlowTask_Runtime As Dts.Runtime.TaskHost = CType(PipelineTask, Dts.Runtime.TaskHost)
  DataFlowTask_Runtime.Name = "MyCustom Data Flow Task"

  Dim DataFlowTask_DesignTime As MainPipe = CType(DataFlowTask_Runtime.InnerObject, MainPipe)

  '------------------
  'SETUP CONNECTIONS
  '------------------
  'CREATE FLAT FILE CONNECTION
  Dim FFConnectionManager As ConnectionManager = package.Connections.Add("FLATFILE")
  FFConnectionManager.ConnectionString = FileName
  FFConnectionManager.Name = "Flat File Source Connection"

  'SETUP FLAT FILE COLUMNS AND DELIMETERS
  GetColumnsFromFlatFile(FFConnectionManager, DelimeterType.CarriageReturnLineFeed, DelimeterType.LineFeed, DelimeterType.Tab, 0)

  '-----------------------
  'CREATE SOURCE COMPONENT
  '-----------------------
  ' Set up the souce component of the Dataflow task
  Dim FFSourceComponent As IDTSComponentMetaData100 = DataFlowTask_DesignTime.ComponentMetaDataCollection.New
  FFSourceComponent.Name = "Flat File Source"

  ' The managed source is an instantiation of the source.
  FFSourceComponent.ComponentClassID = "{D23FD76B-F51D-420F-BBCB-19CBF6AC1AB4}"
  Dim FFSourceComponent_DesignTime As Microsoft.SqlServer.Dts.Pipeline.Wrapper.CManagedComponentWrapper = FFSourceComponent.Instantiate
  FFSourceComponent_DesignTime.ProvideComponentProperties()

  ' Link the connection to the source component.
  If FFSourceComponent.RuntimeConnectionCollection.Count > 0 Then
    FFSourceComponent.RuntimeConnectionCollection(0).ConnectionManager = DtsConvert.GetExtendedInterface(FFConnectionManager)
    FFSourceComponent.RuntimeConnectionCollection(0).ConnectionManagerID = FFConnectionManager.ID
  End If
  FFSourceComponent_DesignTime.AcquireConnections(Nothing)
  FFSourceComponent_DesignTime.ReinitializeMetaData()


  '------------------------------------------
  'Create Output Mappings from the flat file.
  '------------------------------------------
  Dim OutputColumnCollection As IDTSOutputColumnCollection100
  OutputColumnCollection = FFSourceComponent.OutputCollection(0).OutputColumnCollection

  Dim exOutColumn As IDTSExternalMetadataColumn100
  For Each OutputColumn As IDTSOutputColumn100 In OutputColumnCollection
    exOutColumn = FFSourceComponent.OutputCollection(0).ExternalMetadataColumnCollection(OutputColumn.Name)
    FFSourceComponent_DesignTime.MapOutputColumn(FFSourceComponent.OutputCollection(0).ID, OutputColumn.ID, exOutColumn.ID, True)
    'Add the output column name and ID to an array so that we can identify them at a later stage
    outputColumnLineageIDs.Add(OutputColumn.Name, OutputColumn.ID)
  Next
  FFSourceComponent_DesignTime.ReleaseConnections()

  '----------------------------
  'CREATE MYCUSTOM SCRIPT COMPONENT
  '----------------------------

  Dim MyCustomScriptComponent As IDTSComponentMetaData100 = DataFlowTask_DesignTime.ComponentMetaDataCollection.New
  MyCustomScriptComponent.ComponentClassID = "MyCustomBuffer.CustomComponents.MyCustomScriptComponent, MyCustomBuffer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=516f7fc6acf0e6e0"
  MyCustomScriptComponent.Name = "MyCustom Script"

  Dim MyCustomScriptComponent_DesignTime As CManagedComponentWrapper = MyCustomScriptComponent.Instantiate
  MyCustomScriptComponent_DesignTime.ProvideComponentProperties()

  ' Create the path from source to destination.
  Dim path As IDTSPath100 = DataFlowTask_DesignTime.PathCollection.New
  path.AttachPathAndPropagateNotifications(FFSourceComponent.OutputCollection(0), MyCustomScriptComponent.InputCollection(0))

  ' Get the destination's default input and virtual input.
  Dim InputMyCustom As IDTSInput100 = MyCustomScriptComponent.InputCollection(0)
  Dim vInputMyCustom As IDTSVirtualInput100 = InputMyCustom.GetVirtualInput

  MyCustomScriptComponent_DesignTime.ReinitializeMetaData()

  ' Iterate through the virtual input column collection.
  For Each vColumn As IDTSVirtualInputColumn100 In vInputMyCustom.VirtualInputColumnCollection
    ' Call the SetUsageType method of the destination
    '  to add each available virtual input column as an input column.
    Dim InputCol As IDTSInputColumn100 = MyCustomScriptComponent_DesignTime.SetUsageType(InputMyCustom.ID, vInputMyCustom, vColumn.LineageID, DTSUsageType.UT_READONLY)
  Next

  '----------------------------
  'CREATE FLAT FILE DESTINATION
  '----------------------------

  Dim DestFFConnManager As ConnectionManager = package.Connections.Add("FLATFILE")
  DestFFConnManager.ConnectionString = "C:\Test\MyCustomBufferTest.txt"
  DestFFConnManager.Name = "Flat File Destination Connection"

  Dim DestFFConnManager_DesignTime As IDTSConnectionManagerFlatFile100 = DestFFConnManager.InnerObject
  DestFFConnManager_DesignTime.ColumnNamesInFirstDataRow = True
  DestFFConnManager_DesignTime.CodePage = 1252
  DestFFConnManager_DesignTime.HeaderRowDelimiter = vbTab
  DestFFConnManager_DesignTime.Format = "Delimited"
  DestFFConnManager_DesignTime.HeaderRowsToSkip = 0
  'FlatFileConnection.TextQualifier = ""
  DestFFConnManager_DesignTime.RowDelimiter = vbTab

  'CREATE FLAT FILE DESTINATION
  Dim FFDestination As IDTSComponentMetaData100 = DataFlowTask_DesignTime.ComponentMetaDataCollection.New
  FFDestination.ComponentClassID = "{8DA75FED-1B7C-407D-B2AD-2B24209CCCA4}"
  FFDestination.Name = "Flat File Destination"

  Dim FFDestination_DesignTime As CManagedComponentWrapper = FFDestination.Instantiate
  FFDestination_DesignTime.ProvideComponentProperties()

  ' Link the connection to the source component.
  If FFDestination.RuntimeConnectionCollection.Count > 0 Then
    FFDestination.RuntimeConnectionCollection(0).ConnectionManager = DtsConvert.GetExtendedInterface(DestFFConnManager)
    FFDestination.RuntimeConnectionCollection(0).ConnectionManagerID = DestFFConnManager.ID
  End If
  Dim Destpath As IDTSPath100 = DataFlowTask_DesignTime.PathCollection.[New]
  Destpath.AttachPathAndPropagateNotifications(MyCustomScriptComponent.OutputCollection(0), FFDestination.InputCollection(0))

  Dim DestInput As IDTSInput100 = FFDestination.InputCollection(0)
  Dim VDestinput As IDTSVirtualInput100 = DestInput.GetVirtualInput()
  Dim VDestInputColCollection As IDTSVirtualInputColumnCollection100 = VDestinput.VirtualInputColumnCollection


  Dim indexMax As Integer = VDestInputColCollection.Count - 1
  For index As Integer = 0 To indexMax
    ' Get input column to replicate in flat file
    Dim virtualInputColumn As IDTSVirtualInputColumn100 = VDestInputColCollection(index)

    ' Add column to Flat File connection manager
    Dim flatFileColumn As IDTSConnectionManagerFlatFileColumn100 = TryCast(DestFFConnManager_DesignTime.Columns.Add(), IDTSConnectionManagerFlatFileColumn100)
    flatFileColumn.ColumnType = "Delimited"
    flatFileColumn.ColumnWidth = virtualInputColumn.Length
    flatFileColumn.DataPrecision = virtualInputColumn.Precision
    flatFileColumn.DataScale = virtualInputColumn.Scale
    flatFileColumn.DataType = virtualInputColumn.DataType
    Dim columnName As IDTSName100 = TryCast(flatFileColumn, IDTSName100)
    columnName.Name = virtualInputColumn.Name

    If index < indexMax Then
      flatFileColumn.ColumnDelimiter = vbTab
    Else
      flatFileColumn.ColumnDelimiter = vbCrLf
    End If
  Next

  FFDestination_DesignTime.AcquireConnections(Nothing)
  FFDestination_DesignTime.ReinitializeMetaData()

  For Each virtualInputColumn As IDTSVirtualInputColumn100 In VDestInputColCollection
    ' Select column, and retain new input column
    Dim inputColumn As IDTSInputColumn100 = FFDestination_DesignTime.SetUsageType(DestInput.ID, VDestinput, virtualInputColumn.LineageID, DTSUsageType.UT_READONLY)
    ' Find external column by name
    Dim externalColumn As IDTSExternalMetadataColumn100 = DestInput.ExternalMetadataColumnCollection(inputColumn.Name)
    ' Map input column to external column
    FFDestination_DesignTime.MapInputColumn(DestInput.ID, inputColumn.ID, externalColumn.ID)
  Next

Catch ex As Exception
  MsgBox(ex.Message)
End Try

宛先フラット ファイル コンポーネントを追加すると、パッケージを実行できるようになりましたが、カスタム コンポーネント タイプが宛先アダプタであるため意味がありません。追加の宛先フラット ファイル コンポーネントは非効率的であり、その必要性を知りたいです。

4

1 に答える 1

0

カスタム コンポーネントの検証中にエラーが発生する可能性があります。次のことを行う必要があります。

カスタム コンポーネントの遅延検証プロパティを true に設定します。

于 2013-03-06T20:18:08.793 に答える