如何在 SSIS 脚本组件中按名称循环列?
How can I loop though columns by name in an SSIS Script component?
我正在将竖线分隔的平面文件加载到暂存 table。在加载过程中,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
How can I get the column Value in Script Component in SSIS?
简单的解决方法
您可以使用循环将列名称存储在 List(of string)
中,并使用 Row.GetType().GetProperties()
动态操作列。
示例:
注意:您必须导入 System.Reflection
、 System.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
您还可以过滤列表中的列名
Dim lstDateColumns As New List(Of String)
Dim lstSystemColumns As New List(Of String)
For i As Integer = 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().Where(Function(x) lstDateColumns.Contains(x.Name))
dataColumn.SetValue(Row, diagnosisDate, Nothing)
Next
For Each dataColumn As PropertyInfo In Row.GetType().GetProperties().Where(Function(x) lstSystemColumns.Contains(x.Name))
dataColumn.SetValue(Row, "ICD10", Nothing)
Next
参考资料
我正在将竖线分隔的平面文件加载到暂存 table。在加载过程中,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
How can I get the column Value in Script Component in SSIS?
简单的解决方法
您可以使用循环将列名称存储在 List(of string)
中,并使用 Row.GetType().GetProperties()
动态操作列。
示例:
注意:您必须导入 System.Reflection
、 System.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
您还可以过滤列表中的列名
Dim lstDateColumns As New List(Of String)
Dim lstSystemColumns As New List(Of String)
For i As Integer = 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().Where(Function(x) lstDateColumns.Contains(x.Name))
dataColumn.SetValue(Row, diagnosisDate, Nothing)
Next
For Each dataColumn As PropertyInfo In Row.GetType().GetProperties().Where(Function(x) lstSystemColumns.Contains(x.Name))
dataColumn.SetValue(Row, "ICD10", Nothing)
Next
参考资料