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 目标
' 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 不会反映脚本本身发生的事情。我在下面包含了使用派生列对象的替代方法。
替代方法:
使用派生列对象。
在派生列转换编辑器中,在“派生列”下使用 drop-down 到 select 替换“your_column_name”
在“表达式”下键入要应用于该列的表达式,即 LTRIM(RTRIM(your_column_name))
唯一的缺点是您必须手动输入每一列。如果您有很多列,这可能是一个漫长的过程。
答案:脚本自动 Trim
- 在 SSIS 中的源和目标之间添加一个 脚本组件。我在数据转换后添加了我的
- 编辑脚本组件。 Select 前一个任务对象中的输出列 仅 。在我的例子中,数据转换的输出列。将每一列更改为 'ReadWrite'
Select脚本然后设计脚本
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 出错。我删除了这两行
谢谢,希望有人觉得这有用! :)
我有一个 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 目标
' 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 不会反映脚本本身发生的事情。我在下面包含了使用派生列对象的替代方法。
替代方法:
使用派生列对象。
在派生列转换编辑器中,在“派生列”下使用 drop-down 到 select 替换“your_column_name”
在“表达式”下键入要应用于该列的表达式,即 LTRIM(RTRIM(your_column_name))
唯一的缺点是您必须手动输入每一列。如果您有很多列,这可能是一个漫长的过程。
答案:脚本自动 Trim
- 在 SSIS 中的源和目标之间添加一个 脚本组件。我在数据转换后添加了我的
- 编辑脚本组件。 Select 前一个任务对象中的输出列 仅 。在我的例子中,数据转换的输出列。将每一列更改为 'ReadWrite'
Select脚本然后设计脚本
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 出错。我删除了这两行
谢谢,希望有人觉得这有用! :)