如何在SSIS脚本组件中按名称循环列?

时间:2017-10-19 18:41:09

标签: sql-server ssis etl ssis-2012 system.reflection

我正在将一个以管道分隔的平面文件加载到一个临时表中。在加载过程中,SSIS脚本组件对一行执行某些操作。它可以根据另一个字段中的值在一个字段中设置一个标志,为某些列添加前缀或应用格式。例如,如果缺少日期,则会将该字段分配给默认日期。 (如果Row.EndDate_isNull则Row.EndDate = defaultDate)

当需要将相同的转换应用于一系列行时,这些脚本会变得很麻烦。例如,医疗记录文件可以描述具有三个字段的9个诊断中的每一个:Diagnosis01_Date,Diagnosis01_Code,Diagnosis01_System .... Diagnosis09_Date,Diagnosis09_Code,Diagnosis09_System。

我想使用循环来对9个3个字段中的每个字段执行操作,而不是将相同的操作写入9次。

例如,如果我在VB中处理一个集合,我会在Input0_ProcessInputRow子中写下这样的东西:

For i = 1 to 9
   row.("Diagnosis0"+ i + "_Date").Value = diagnosisDate
   row.("Diagnosis0"+ i + "_System").value = "ICD10"
next i 

然而,在SSIS对象模型中,列是作为Input0Buffer的属性公开的,我找不到使用变量来引用它们的方法。那么,如何我如何在SSIS脚本组件中创建一个按名称操作列的循环?

编辑:我发现以下来源,特别是前两个,在我对这个问题进行研究时有所帮助。似乎应该有一个使用system.reflection的解决方案,但我只是不太了解.NET以便弄明白。

http://agilebi.com/jwelch/2007/10/21/address-columns-generically-in-a-script-task/

http://agilebi.com/jwelch/2007/06/02/xml-destination-script-component/

http://microsoft-ssis.blogspot.com/2010/12/do-something-for-all-columns-in-your.html

http://toddmcdermid.blogspot.com/2011/05/iterating-over-columns-in-ssis-script.html

http://bidn.com/blogs/MikeDavis/ssis/1800/ssis-for-each-column-in-a-data-flow

https://social.msdn.microsoft.com/Forums/en-US/edbac1df-f05f-40db-820a-e009fae201a4/using-script-destination-object-to-create-and-write-to-new-text-file?forum=sqlintegrationservices&forum=sqlintegrationservices

https://social.msdn.microsoft.com/Forums/en-US/757d11c8-8ad4-4021-a959-1d13c8dfdaa7/how-to-run-a-loop-for-all-columns-in-script-component-input-column-collection-for-each-row?forum=sqlintegrationservices

How can I get the column Value in Script Component in SSIS?

1 个答案:

答案 0 :(得分:4)

简单解决方法

您可以使用循环在[{1}}中存储列名称,并使用List(of string)动态操作列。

示例:

注意:您必须导入Row.GetType().GetProperties()System.ReflectionSystem.Linq个库

System.Collections.Generic

您可以过滤列表中的列名称

Dim lstDateColumns as new List(of string)
Dim lstSystemColumns as new List(of string)

For i = 1 to 9
    lstDateColumns.Add("Diagnosis0" & i.toString() & "_Date")
    lstSystemColumns.Add("Diagnosis0" & i.toString() & "_System")
Next


For each  dataColumn as PropertyInfo in Row.GetType().GetProperties()


    If lstDateColumns.Contains(dataColumn.Name) Then

                 dataColumn.SetValue(Row, diagnosisDate, Nothing)

     ElseIf lstSystemColumns.Contains(dataColumn.Name) Then

                dataColumn.SetValue(Row, "ICD10", Nothing)

     End IF
Next

<强>参考