我正在尝试在SSIS 2008中创建一个自定义脚本,它将循环选定的输入列并连接它们,以便它们可用于创建SHA1哈希。我知道可用的自定义组件,但我无法在我们的系统上安装它们。
虽然这里提出的示例似乎工作得很好http://www.sqlservercentral.com/articles/Integration+Services+(SSIS)/69766/当我测试了这个只选择了几个而不是所有列时,我得到奇怪的结果。如果选择的列按顺序排列,则该脚本似乎仅起作用。即使它们处于有序状态,在经过如此多的记录或下一个缓冲区之后,尽管我的测试数据中的行完全相同,但仍会生成不同的MD5哈希值。
我试图调整上一个链接中的代码以及这些文章但到目前为止没有任何乐趣。
http://msdn.microsoft.com/en-us/library/ms136020.aspx
http://agilebi.com/jwelch/2007/06/03/xml-transformations-part-2/
作为一个起点,这可以很好地显示我选择用作输入的列名
Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)
For Each inputColumn As IDTSInputColumn100 In Me.ComponentMetaData.InputCollection(0).InputColumnCollection
MsgBox(inputColumn.Name)
Next
End Sub
在此基础上,我尝试使用以下代码获取值:
Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)
Dim column As IDTSInputColumn100
Dim rowType As Type = Row.GetType()
Dim columnValue As PropertyInfo
Dim testString As String = ""
For Each column In Me.ComponentMetaData.InputCollection(0).InputColumnCollection
columnValue = rowType.GetProperty(column.Name)
testString += columnValue.GetValue(Row, Nothing).ToString()
Next
MsgBox(testString)
End Sub
不幸的是,这不起作用,我收到以下错误:
我确信我想要做的事情很容易实现,虽然我对VB.net的知识有限,特别是SSIS中的VB.net,我正在努力。我可以单独定义列名称,如http://timlaqua.com/2012/02/slowly-changing-dimensions-with-md5-hashes-in-ssis/所示,但我想尝试动态方法。
答案 0 :(得分:2)
您的问题是尝试对数据库中的NULL值运行ToString()。
尝试使用Convert.ToString(columnValue),它只返回一个空字符串。
答案 1 :(得分:1)
每次都不保证输入列的顺序相同。因此,只要数据流中的元数据发生更改,您就会获得不同的哈希值。在编写完全相同的脚本时,我也经历了同样的痛苦。
网上的每个答案我都发现了建立自定义组件的状态,以便能够做到这一点。没必要。每次打开脚本组件时,我依靠SSIS为列名生成索引。需要注意的是,只要数据流的元数据发生变化,索引就会发生变化,需要通过重新打开和关闭SSIS脚本组件来更新索引。
您需要重写ProcessInput()以获取存储对PipelineBuffer的引用,而PipelineBuffer不会在ProcessInputRow中公开,您实际上需要使用它来按索引而不是按名称访问列。
名称和相关索引的列表存储在ComponentMetaData.InputCollection [0] .InputColumnCollection中,需要对其进行迭代和排序,以保证每次都使用相同的HASH。
PS。我去年发布了答案,但它消失了,可能是因为它是在C#而不是VB(在SSIS中无关紧要)。您可以在https://gist.github.com/danieljarolim/e89ff5b41b12383c60c7#file-ssis_sha1-cs
找到包含所有丑陋详细信息的代码