Как зациклить столбцы по имени в компоненте сценария служб SSIS?

Я загружаю плоский файл с разделителями трубы в промежуточный стол. В процессе загрузки компонент сценария служб 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

Как получить значение столбца в компоненте сценария в службах SSIS?

1 ответ

Решение

Простой обходной путь

Вы можете сохранить имя столбца в 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

Рекомендации

Другие вопросы по тегам