VB.Net SSIS 脚本 Trim Leading/Trailing 空白的所有输入列

VB.Net SSIS Script to Trim all Input Columns of Leading/Trailing whitespace

我有一个 SSIS 包,它正在将数据从平面文件输入到 SQL 2008 数据库 table。第 3 方每天生成平面文件 (.csv)。我需要删除的每个字段中都有前导空格。

我认为脚本组件可以解决问题?

我想让它遍历所有输入列和 LTrim(RTrim) 每列的所有值。

我在这里找到了这段代码:http://microsoft-ssis.blogspot.com/2010/12/do-something-for-all-columns-in-your.html

但是,我不知道如何将其更改为 Trim 值?

我试过改变 "ValueOfProperty.ToUpper()" 到 "ValueOfProperty.Trim()" 但随后它会导致组件出错 "Error 30203: Identifier expected..."

请帮忙??

这是我的 SSIS 数据流:

平面文件 > 数据转换 > 脚本组件 > OLE DB 目标

Data Flow

    ' 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

我认为您可以使用数据转换任务而不是 SSIS 中的脚本任务来实现此目的。我认为这可能更直接,您可以简单地将每个列上的表达式应用于 trim,或者将新列添加到您的集合并替换旧列 更新由同一列返回的值,然后供您的下一个数据流任务使用。

我个人认为在 GUI drag/drop 中这样做会更好一些,在这种情况下您根本不必考虑脚本任务!只有要使用的表达式,我正在链接一些 MSDN 文档。然后,您可以根据平面文件数据源中的每一列对其进行显式设置。

Trim MSDN 上的文档: https://msdn.microsoft.com/en-us/library/ms139947.aspx

这里的这台家用机器上没有安装 SSDT 或 VSBI,否则我会设置一个简单的数据流示例并截图。

SSIS 中关于 Trim 的另一篇看似有用的文章:http://www.bradleyschacht.com/trim-functions-in-ssis/

我想出了如何让脚本使用 For Each 循环 Trim 所有值。当您有很多列,或者想对多个包使用相同的解决方案时,这很有用。

正如 Dinglemeyer 和 Jim 在评论中所述,缺点是 SSIS 不会反映脚本本身发生的事情。我在下面包含了使用派生列对象的替代方法。

替代方法:

使用派生列对象。

  1. 在派生列转换编辑器中,在“派生列”下使用 drop-down 到 select 替换“your_column_name”

  2. 在“表达式”下键入要应用于该列的表达式,即 LTRIM(RTRIM(your_column_name))

唯一的缺点是您必须手动输入每一列。如果您有很多列,这可能是一个漫长的过程。


答案:脚本自动 Trim

  1. 在 SSIS 中的源和目标之间添加一个 脚本组件。我在数据转换后添加了我的

  1. 编辑脚本组件。 Select 前一个任务对象中的输出列 。在我的例子中,数据转换的输出列。将每一列更改为 'ReadWrite'

  1. Select脚本然后设计脚本

  2. Copy/Paste 下面的代码。保存并 运行

您可以将脚本中的这一行修改为任何其他普通表达式:

ValueOf属性 = LTrim(RTrim(ValueOf属性))

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

一些错误:

"The task is configured to pre-compile the script, but binary code is not found. Please visit the IDE..." 这是一个错误。进入脚本并删除“End Class”。救。在脚本底部添加“End Class”并再次保存。

属性 找不到方法。 添加了“CanWrite”if/then 语句。确保您的列设置为读写,否则它们将被跳过。

错误 30203:需要标识符 确保您在脚本组件的“输入列”下 selected 的列有效。在我的例子中,它显示了这个脚本组件之前数据转换的输入和输出的所有列。需要是前一个数据流对象的输出,因此 select 只有那些列。

原始代码是这样的:

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

导致 =”.sqlserver 出错。我删除了这两行

谢谢,希望有人觉得这有用! :)