Скрипт VB.Net SSIS для обрезки всех входных столбцов начальных/конечных пробелов

У меня есть пакет SSIS, который вводит данные из плоского файла в таблицу базы данных SQL 2008. Каждый день третья сторона создает плоский файл (.csv). В каждом поле есть начальные пробелы, которые мне нужно удалить.

Я думал, что компонент сценария поможет?

Я хочу, чтобы он перебирал все входные столбцы и LTrim (RTrim) все значения для каждого столбца.

Я нашел этот код здесь: http://microsoft-ssis.blogspot.com/2010/12/do-something-for-all-columns-in-your.html

Но я не знаю, как изменить его на Обрезать значения?

Я попытался изменить "ValueOfProperty.ToUpper()" на "ValueOfProperty.Trim()", но затем это вызывает ошибку в компоненте "Ошибка 30203: ожидается идентификатор.. ."

Помоги пожалуйста??

Вот мой поток данных SSIS:

Плоский файл > Преобразование данных > Компонент скрипта > Назначение OLE DB

Поток данных

    ' This script adjusts the value of all string fields
Imports System
Imports System.Data
Imports System.Math
Imports System.Reflection ' Added
Imports Microsoft.SqlServer.Dts.Pipeline.Wrapper
Imports Microsoft.SqlServer.Dts.Runtime.Wrapper

<microsoft .sqlserver.dts.pipeline.ssisscriptcomponententrypointattribute=".sqlserver.dts.pipeline.ssisscriptcomponententrypointattribute"> _
<clscompliant false="false"> _

Public Class ScriptMain
Inherits UserComponent

' Method that will be started for each record in you dataflow 
Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)
    ' Use Reflection to loop through all the properties of Row:
    ' Example:
    ' Row.Field1            (String)
    ' Row.Field1_IsNull     (Boolean)
    ' Row.Field2            (String)
    ' Row.Field2_IsNull     (Boolean)
    Dim p As PropertyInfo
    For Each p In Row.GetType().GetProperties()
        ' Do something for all string properties: Row.Field1, Row.Field2, etc.
        If p.PropertyType Is GetType(String) Then
            ' Use a method to set the value of each String type property
            ' Make sure the length of the new value doesn't exceed the column size
            p.SetValue(Row, DoSomething(p.GetValue(Row, Nothing).ToString()), Nothing)
        End If
    Next
End Sub

' New function that you can adjust to suit your needs
Public Function DoSomething(ByVal ValueOfProperty As String) As String
    ' Uppercase the value
    ValueOfProperty = ValueOfProperty.ToUpper() 'Maybe change this to Trim()?
    Return ValueOfProperty
End Function

End Class

person Gemini    schedule 18.04.2016    source источник


Ответы (2)


Я думаю, вы могли бы добиться этого с помощью задачи преобразования данных вместо задачи сценария в SSIS. Я думаю, что это может быть более простым, и вы можете просто применить выражение к каждому столбцу для обрезки, либо добавив новый столбец в свой набор, либо заменив старый столбец ИЛИ обновив значение, возвращаемое тем же столбцом, на затем использоваться вашей следующей задачей потока данных.

Я лично думаю, что это будет немного лучше сделать в графическом интерфейсе с помощью перетаскивания, и в этом случае вам вообще не придется рассматривать задачу сценария! Только используемое выражение, на которое я ссылаюсь на документацию MSDN. Затем вы можете установить его явно на основе каждого столбца, который у вас есть в вашем источнике данных плоского файла.

Обрезать документацию в MSDN: https://msdn.microsoft.com/en-us/library/ms139947.aspx

Не устанавливайте SSDT или VSBI на этом домашнем компьютере, иначе я бы настроил простой пример потока данных и сделал снимок экрана.

Еще одна полезная статья об Trim в SSIS: http://www.bradleyschacht.com/trim-functions-in-ssis/

person Dinglemeyer NeverGonnaGiveUUp    schedule 19.04.2016
comment
Согласен - я избегаю скриптов без крайней необходимости, не в последнюю очередь потому, что визуально вы не можете увидеть, что происходит, не вникая в код. - person BIDeveloper; 19.04.2016
comment
Это правда, Джим. Я надеюсь, что теперь Gemini будет легче запускать свой пакет SSIS. Задачи-скрипты — мой враг - person Dinglemeyer NeverGonnaGiveUUp; 19.04.2016
comment
Спасибо, Динглемейер! Я не вижу, где сделать выражение для преобразования данных, но вы привели меня к использованию производного столбца, где я могу ввести выражение ltrim(rtrim(mycolumn)) и заменить существующий столбец. Я никогда не использовал это раньше, но я думаю, что это сработает? Это то, о чем ты думал? - person Gemini; 19.04.2016
comment
Это сработает! :) Я думаю, что есть как преобразование данных, так и производный столбец, любой из них позволяет вам запустить этот пакет и работать со мной! Я рад, что у тебя все получилось. Я думаю, это удовлетворит ваши потребности. Отправьте еще один комментарий, если вы застряли, и я постараюсь продолжить помогать вашему квесту SSIS. :) - person Dinglemeyer NeverGonnaGiveUUp; 19.04.2016

Я понял, как заставить скрипт обрезать все значения с помощью цикла For Each. Это полезно, когда у вас много столбцов или вы хотите использовать одно и то же решение для нескольких пакетов.

Как заявили в комментариях Динглемейер и Джим, недостатком является то, что SSIS не будет отражать то, что происходит в самом скрипте. Ниже я включил альтернативный метод использования объекта производного столбца.

Альтернативный метод:

Используйте объект Производный столбец.

  1. В редакторе преобразования производных столбцов в разделе «Производный столбец» используйте раскрывающийся список, чтобы выбрать Заменить «your_column_name».

  2. В поле «Выражение» введите выражение, которое вы хотите применить к этому столбцу, например LTRIM(RTRIM(your_column_name))

введите здесь описание изображения

Единственным недостатком является то, что вам придется вводить каждый столбец вручную. Это может быть длительным процессом, если у вас много столбцов.


ОТВЕТ: Скрипт для автоматической обрезки

  1. Добавьте компонент скрипта между источником и местом назначения в SSIS. Я добавил свой после преобразования данных

введите здесь описание изображения

  1. Отредактируйте компонент сценария. Выберите выходные столбцы только из предыдущего объекта задачи. В моем случае столбцы вывода из преобразования данных. Измените каждый столбец на «ReadWrite».

введите здесь описание изображения

  1. Выберите «Сценарий», а затем Сценарий дизайна.

  2. Скопируйте/вставьте приведенный ниже код. Сохранить и запустить

Вы можете изменить эту строку в скрипте на любое другое нормальное выражение:

ValueOfProperty = LTrim(RTrim(ValueOfProperty))

введите здесь описание изображения

Imports System
Imports System.Data
Imports System.Math
Imports System.Reflection ' Added
Imports Microsoft.SqlServer.Dts.Pipeline.Wrapper
Imports Microsoft.SqlServer.Dts.Runtime.Wrapper



Public Class ScriptMain
Inherits UserComponent

Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)
    '
    ' Use Reflection to loop through all the properties of Row:
    ' Example:
    ' Row.Field1            (String)
    ' Row.Field1_IsNull     (Boolean)
    ' Row.Field2            (String)
    ' Row.Field2_IsNull     (Boolean)
    Dim p As PropertyInfo
    For Each p In Row.GetType().GetProperties()
        ' Do something for all string properties: Row.Field1, Row.Field2, etc.
        If p.PropertyType Is GetType(String) Then
            ' Use a method to set the value of each String type property
            ' Make sure the length of the new value doesn't exceed the column size
            If (p.CanWrite) Then p.SetValue(Row, DoSomething(p.GetValue(Row, Nothing).ToString()), Nothing)
        End If

    Next
    '
End Sub
' New function that you can adjust to suit your needs
Public Function DoSomething(ByVal ValueOfProperty As String) As String
    ' Uppercase the value
    'ValueOfProperty = ValueOfProperty.ToUpper()

    'Trim Leading (LTrim) and Trailing (RTrim) Whitespace 
    'Change this to equal any normal expression
    ValueOfProperty = LTrim(RTrim(ValueOfProperty))

    Return ValueOfProperty
End Function
End Class

введите здесь описание изображения

Некоторые ошибки:

"Задача настроена на предварительную компиляцию скрипта, но двоичный код не найден. Зайдите в IDE..." Это ошибка. Зайдите в сценарий и удалите «Конец класса». Сохранять. Добавьте «End Class» обратно в конец сценария и снова сохраните.

Метод свойства не найден. Добавлен оператор «CanWrite» if/then. Убедитесь, что ваши столбцы настроены на чтение и запись, иначе они будут пропущены.

Ошибка 30203: ожидается идентификатор Убедитесь, что столбцы, выбранные вами в разделе «Входные столбцы» в компоненте скрипта, допустимы. В моем случае он показывал все столбцы из ввода и вывода преобразования данных непосредственно перед этим компонентом сценария. Должен быть выходом из предыдущего объекта потока данных, поэтому выберите только эти столбцы.

В исходном коде было так:

<microsoft .sqlserver.dts.pipeline.ssisscriptcomponententrypointattribute=".sqlserver.dts.pipeline.ssisscriptcomponententrypointattribute"> _
<clscompliant false="false"> 

Это вызвало ошибку на =".sqlserver. Я удалил эти две строки

Спасибо, и, надеюсь, кому-то это будет полезно! :)

person Gemini    schedule 19.04.2016
comment
Это законно. Я пересылаю это всем членам моей команды, которым нужно обрезать данные в пакете SSIS. Хорошо пиши! - person Dinglemeyer NeverGonnaGiveUUp; 20.04.2016
comment
Спасибо Динглемейеру за помощь! - person Gemini; 20.04.2016