了解脚本组件对象模型
适用范围:SQL Server Azure 数据工厂中的 SSIS Integration Runtime
如脚本组件的编码和调试中所述,脚本组件项目包含三个项目项:
ScriptMain 项,该项包含要用来编写代码的 ScriptMain 类 。 ScriptMain 类继承自 UserComponent 类 。
ComponentWrapper 项包含 UserComponent 类,该类是 ScriptComponent(包含用于处理数据和与包交互的方法和属性)的实例 。 ComponentWrapper 项还包含 Connections 和 Variables 集合类 。
BufferWrapper 项,该项包含的类继承自每个输入和输出的 ScriptBuffer,该项还包含每一列的类型化属性 。
当在 ScriptMain 项中编写代码时,将使用本主题中讨论的对象、方法和属性 。 每个组件不会用到此处列出的所有方法;但用到的方法都会按照此处所示的顺序。
ScriptComponent 基类不包含本主题中讨论的方法的任何实现代码。 因此没有必要(但是无害)将对基类实现的调用添加到您自己的方法实现中。
有关如何在特定类型的脚本组件中使用这些类的方法和属性的信息,请参阅其他脚本组件示例一节。 该示例主题还包含完整的代码示例。
AcquireConnections 方法
源和目标通常必须连接到外部数据源。 请重写 AcquireConnections 基类的 ScriptComponent 方法,以从相应的连接管理器获得连接或连接信息。
下面的示例从 ADO.NET 连接管理器返回 System.Data.SqlClient.SqlConnection 。
Dim connMgr As IDTSConnectionManager100
Dim sqlConn As SqlConnection
Public Overrides Sub AcquireConnections(ByVal Transaction As Object)
connMgr = Me.Connections.MyADONETConnection
sqlConn = CType(connMgr.AcquireConnection(Nothing), SqlConnection)
End Sub
下面的示例从平面文件连接管理器返回完整的路径和文件名,然后使用 System.IO.StreamReader 打开该文件 。
Private textReader As StreamReader
Public Overrides Sub AcquireConnections(ByVal Transaction As Object)
Dim connMgr As IDTSConnectionManager100 = _
Me.Connections.MyFlatFileSrcConnectionManager
Dim exportedAddressFile As String = _
CType(connMgr.AcquireConnection(Nothing), String)
textReader = New StreamReader(exportedAddressFile)
End Sub
PreExecute 方法
如果您有必须仅在开始处理数据行之前执行一次的处理,请重写 PreExecute 基类的 ScriptComponent 方法。 例如,在目标中,您可能希望配置参数化的命令,供目标将每个数据行插入到数据源中。
Dim sqlConn As SqlConnection
Dim sqlCmd As SqlCommand
Dim sqlParam As SqlParameter
...
Public Overrides Sub PreExecute()
sqlCmd = New SqlCommand("INSERT INTO Person.Address2(AddressID, City) " & _
"VALUES(@addressid, @city)", sqlConn)
sqlParam = New SqlParameter("@addressid", SqlDbType.Int)
sqlCmd.Parameters.Add(sqlParam)
sqlParam = New SqlParameter("@city", SqlDbType.NVarChar, 30)
sqlCmd.Parameters.Add(sqlParam)
End Sub
SqlConnection sqlConn;
SqlCommand sqlCmd;
SqlParameter sqlParam;
public override void PreExecute()
{
sqlCmd = new SqlCommand("INSERT INTO Person.Address2(AddressID, City) " + "VALUES(@addressid, @city)", sqlConn);
sqlParam = new SqlParameter("@addressid", SqlDbType.Int);
sqlCmd.Parameters.Add(sqlParam);
sqlParam = new SqlParameter("@city", SqlDbType.NVarChar, 30);
sqlCmd.Parameters.Add(sqlParam);
}
处理输入和输出
处理输入
配置为转换或目标的脚本组件有一个输入。
BufferWrapper 项目项提供的内容
对于已配置的每个输出,BufferWrapper 项目项包含从 ScriptBuffer 派生并且与输入同名的类 。 每个输入缓冲区类包含以下属性、函数和方法:
每个所选输入列的已命名类型化取值函数属性。 这些属性是只读或读/写的,取决于在“脚本转换编辑器”的“输入列”页中为该列指定的“使用类型” 。
每个所选输入列的 <column>_IsNull 属性。 此属性也是只读或读/写的,取决于为该列指定的“使用类型” 。
为每个已配置的输出使用 DirectRowTo<outputbuffer> 方法。 在将行筛选到位于同一 ExclusionGroup 中的多个输出之一时,将使用这些方法 。
一个 NextRow 函数,用于获取下一个输入行,以及一个 EndOfRowset 函数,用于确定最后一个数据缓冲区是否已经处理 。 使用在 UserComponent 基类中实现的输入处理方法时,通常不需要这些函数 。 下一节提供有关 UserComponent 基类的详细信息 。
ComponentWrapper 项目项提供的内容
ComponentWrapper 项目项包含从 ScriptComponent 派生的名为 UserComponent 的类 。 要用来编写自定义代码的 ScriptMain 类又派生自 UserComponent 。 UserComponent 类包含以下方法 :
ProcessInput 方法的重写实现 。 这是数据流引擎在运行时继调用 PreExecute 方法后调用的下一个方法,该方法可被调用多次 。 ProcessInput 将处理过程移交给 <inputbuffer>_ProcessInput 方法。 然后 ProcessInput 方法检查是否已到达输入缓冲区的末尾,如果已到达缓冲区末尾,则调用可重写的 FinishOutputs 方法和私有 MarkOutputsAsFinished 方法 。 然后,MarkOutputsAsFinished 方法对最后一个输出缓冲区调用 SetEndOfRowset 。
<inputbuffer>_ProcessInput 方法的可重写实现。 此默认实现只是遍历每个输入行并调用 <inputbuffer>_ProcessInputRow。
<inputbuffer>_ProcessInputRow 方法的可重写实现。 默认实现为空。 通常会重写此方法以编写自定义数据处理代码。
自定义代码应执行的操作
可以使用以下方法在 ScriptMain 类中处理输入 :
重写 <inputbuffer>_ProcessInputRow 以便在每个输入行通过时处理其中的数据。
仅当你在遍历输入行时必须执行附加操作时,才重写 <inputbuffer>_ProcessInput。 (例如,必须测试 EndOfRowset,以便在所有行都处理完毕后进行其他一些操作。)调用 <inputbuffer>_ProcessInputRow 以便执行行处理。
如果必须在关闭输出之前对输出进行一些操作,请重写 FinishOutputs 。
ProcessInput 方法确保以合适的次数调用这些方法 。
处理输出
配置为源或转换的脚本组件有一个或多个输出。
BufferWrapper 项目项提供的内容
对于已配置的每个输出,BufferWrapper 项目项包含从 ScriptBuffer 派生并且与输出同名的类。 每个输入缓冲区类包含以下属性和方法:
每个输出列的已命名类型化只写取值函数属性。
每个所选输出列的只写 <column>_IsNull 属性,可用于将列值设置为 null。
一个 AddRow 方法,用于将空的新行添加到输出缓冲区 。
一个 SetEndOfRowset 方法,用于通知数据流引擎没有数据缓冲区了 。 还有一个 EndOfRowset 函数,用于确定当前缓冲区是否是最后一个数据缓冲区 。 使用在 UserComponent 基类中实现的输入处理方法时,通常不需要这些函数 。
ComponentWrapper 项目项提供的内容
ComponentWrapper 项目项包含从 ScriptComponent 派生的名为 UserComponent 的类 。 要用来编写自定义代码的 ScriptMain 类又派生自 UserComponent 。 UserComponent 类包含以下方法 :
PrimeOutput 方法的重写实现 。 在运行时,数据流引擎在调用 ProcessInput 之前调用此方法,而且只调用一次 。 PrimeOutput 将处理过程移交给 CreateNewOutputRows 方法 。 然后,如果该组件是源(也就是说组件没有输入),则 PrimeOutput 调用可重写的 FinishOutputs 方法和私有 MarkOutputsAsFinished 方法 。 MarkOutputsAsFinished 方法会对最后一个输出缓冲区调用 SetEndOfRowset 。
CreateNewOutputRows 方法的可重写实现 。 默认实现为空。 通常会重写此方法以编写自定义数据处理代码。
自定义代码应执行的操作
可以使用以下方法在 ScriptMain 类中处理输出 :
仅当可以在处理输入行之前添加和填充输出行时,重写 CreateNewOutputRows 。 例如,可以在源中使用 CreateNewOutputRows,但在带有异步输出的转换中,应在输入数据处理期间或之后调用 AddRow 。
如果必须在关闭输出之前对输出进行一些操作,请重写 FinishOutputs 。
PrimeOutput 方法确保以合适的次数调用这些方法 。
PostExecute 方法
如果您有必须仅在处理完数据行之后执行一次的处理,请重写 PostExecute 基类的 ScriptComponent 方法。 例如,在源中,可能需要关闭曾用来将数据加载到数据流中的 System.Data.SqlClient.SqlDataReader 。
重要
ReadWriteVariables 的集合仅适用于 PostExecute 方法 。 因此不能在处理每行数据时直接递增包变量的值, 而应递增本地变量的值,并在所有数据处理完毕后,在 PostExecute 方法中将包变量的值设置为本地变量的值 。
ReleaseConnections 方法
源和目标通常必须连接到外部数据源。 请重写 ReleaseConnections 基类的 ScriptComponent 方法,以关闭和释放先前在 AcquireConnections 方法中打开的连接。
Dim connMgr As IDTSConnectionManager100
...
Public Overrides Sub ReleaseConnections()
connMgr.ReleaseConnection(sqlConn)
End Sub
IDTSConnectionManager100 connMgr;
public override void ReleaseConnections()
{
connMgr.ReleaseConnection(sqlConn);
}