具有优先约束的文件名子串 - SSIS
File name substring with precedence constraint - SSIS
我正在通过 SQL 任务使用基于表达式的约束来确定我的 For Each File 循环是否将平面文件添加到我的数据库对象中。这是基于平面文件名的第一个字符的值。到目前为止采取的步骤:
使用表达式 SubString = SUBSTRING(@[User::FileFound], 1, 1)
添加了执行 SQL 任务。
将结果集设置为 SingleRow
。我设置的结果集的结果名称为 SubString
,变量名称为 User::SubString
.
然后对于我的优先约束,我使用了 @[User::SubString] = "9"
的表达式,它使用 'Test' 按钮成功验证。
但是我在屏幕上打印了以下错误文本:
[Execute SQL Task] Error: Executing the query "SubString = SUBSTRING(@[User::FileFound], 1, 1)" failed with the following error: "Incorrect syntax near '='.". Possible failure reasons: Problems with the query, "ResultSet" property not set correctly, parameters not set correctly, or connection not established correctly.
我的变量 FileFound 是一个字符串,其中包含在循环中解析的平面文件名,而 SubString 是一个布尔值。我尝试将 Substring 设置为字符串变量,但收到以下错误消息:
TITLE: Package Validation Error
------------------------------
Package Validation Error
------------------------------
ADDITIONAL INFORMATION:
Error at Foreach Loop Container: The expression "@[User::SubString] = "9"" must evaluate to True or False. Change the expression to evaluate to a Boolean value.
Error at Foreach Loop Container: There was an error in the precedence constraint between "Execute SQL Task" and "Data Flow Task".
(Microsoft.DataTransformationServices.VsIntegration)
------------------------------
BUTTONS:
OK
------------------------------
感觉自己走在了正确的轨道上,只是遗漏了一些东西。
谢谢
有些地方看起来不对。
对于你的先例约束
The expression "@[User::SubString] = "9"" must evaluate to True or False
您正在尝试使用赋值运算符,=
未测试相等性 ==
在你的执行 SQL 任务中,你表明你有这个片段
SubString = SUBSTRING(@[User::FileFound], 1, 1)
第一,你不能混合那样的东西。如果你有一个查询,它通常需要是一个对目标数据库 运行 的查询。该规则的例外是参数,这是我 认为 您正在尝试做的。
要修复查询,您需要为提供程序使用适当的参数化类型(OLE = ?
、ADO = @Param
、ODBC = ?
),因此它变成像
SubString = SUBSTRING('?', 1, 1)
但这不会是本地 SSIS 人员完成识别变量前导字符的根本任务的方式。
重做
你有一个名为 FileFound
的变量,它包含文件名,你有一个名为 SubString
的变量,你想保存 FileFound
的第一个字符。
我会跳过使用执行 SQL 任务,而是在我们的变量 SubString
中完成工作
对于 2005/2008,右键单击变量和 select 属性。找到两个属性:EvaluateAsExpression
并将其设置为 True,对于 Expression
将其设置为 SUBSTRING(@[User::FileFound], 1, 1)
请注意,我们没有以 A = B 的形式提供显式赋值。相反,我们正在设置我们变量上的 属性 是评估操作的结果。这种方法的美妙之处在于,每次你去访问变量时,它都会评估自己并且你有正确的值。使用您的方法,您需要保留 运行ning 该任务,并可能在需要时复制和粘贴它。
对于 2012+,他们简化了设置表达式的点击路径。您所要做的就是将表达式放入变量 window 的表达式框中,然后自动设置 EvaluateAsExpression。
最后,创建变量对性能没有任何影响。您可以在执行 SSIS 包的任何时候检查变量的值。您可以将它们打印到屏幕上,记录到文件中,随心所欲。您不能做的是查看对象(任务、先例约束等)上存在的表达式的值。如果您对先例约束的逻辑表现得很滑稽——您如何查看执行时的值是什么?你不能。
但是如果您创建第三个变量,ProcessFile
将其设为布尔类型,然后在其上使用表达式 @[User::SubString] == "9"
,看看会发生什么。您可以设置一个断点并确保您的逻辑正确,您可以为任何处理日志发出该值,当逻辑发生变化时(因为我们需要 9 和 7 文件),您可以在一个地方进行更改,所有以我们的新变量 "just work."
的值为关键字的地方
综合起来
选项 1
在您的 foreach 枚举器中,您需要一个父任务才能将先例约束添加到实际工作的任务中。在这里我使用了一个序列容器,因为它使用起来不花钱,而且通过这样命名,它的目的是显而易见的。由于 ProcessFile 是布尔值,我使用 @[User::ProcessFile]
的 shorthand 符号作为我的表达式。不用写@[User::ProcessFile] == true
选项 2
由于您从未从全局角度指定要尝试做什么,因此您可以调整 Foreach 循环容器以仅查找所有 9*.* 文件。那么您不需要 SubString 或 ProcessFile 变量。枚举器将拾取的唯一内容是以 9
开头的文件
Foreach 文件枚举器。在 Files 部分,您指定要加载的内容。在这里我指定 9*.txt
它将查找所有以 9 开头并以 .txt 扩展名结尾的文件
如果我对你的理解正确,你想要实现的是根据来自先前 ExecuteSQLTask 的某些条件启动循环。
那么它是否归结为这样的事情:
如果是这样,那么这就是我所做的:
a) 获取ResultSet到一个变量中
b) 使用变量并评估它是否为 9
注意:您需要指定两个 (!)= 符号。然后表达式的计算结果为 true 或 false(请参阅上面抱怨此错误的错误)
为了演示,我创建了两个流程来展示条件匹配时会发生什么,一个流程不匹配时会发生什么。
注意:我没有配置Foreach Loop Container.That 是Data Flow Task不绿的原因。它从未被调用过。
我正在通过 SQL 任务使用基于表达式的约束来确定我的 For Each File 循环是否将平面文件添加到我的数据库对象中。这是基于平面文件名的第一个字符的值。到目前为止采取的步骤:
使用表达式 SubString = SUBSTRING(@[User::FileFound], 1, 1)
添加了执行 SQL 任务。
将结果集设置为 SingleRow
。我设置的结果集的结果名称为 SubString
,变量名称为 User::SubString
.
然后对于我的优先约束,我使用了 @[User::SubString] = "9"
的表达式,它使用 'Test' 按钮成功验证。
但是我在屏幕上打印了以下错误文本:
[Execute SQL Task] Error: Executing the query "SubString = SUBSTRING(@[User::FileFound], 1, 1)" failed with the following error: "Incorrect syntax near '='.". Possible failure reasons: Problems with the query, "ResultSet" property not set correctly, parameters not set correctly, or connection not established correctly.
我的变量 FileFound 是一个字符串,其中包含在循环中解析的平面文件名,而 SubString 是一个布尔值。我尝试将 Substring 设置为字符串变量,但收到以下错误消息:
TITLE: Package Validation Error
------------------------------
Package Validation Error
------------------------------
ADDITIONAL INFORMATION:
Error at Foreach Loop Container: The expression "@[User::SubString] = "9"" must evaluate to True or False. Change the expression to evaluate to a Boolean value.
Error at Foreach Loop Container: There was an error in the precedence constraint between "Execute SQL Task" and "Data Flow Task".
(Microsoft.DataTransformationServices.VsIntegration)
------------------------------
BUTTONS:
OK
------------------------------
感觉自己走在了正确的轨道上,只是遗漏了一些东西。
谢谢
有些地方看起来不对。
对于你的先例约束
The expression "@[User::SubString] = "9"" must evaluate to True or False
您正在尝试使用赋值运算符,=
未测试相等性 ==
在你的执行 SQL 任务中,你表明你有这个片段
SubString = SUBSTRING(@[User::FileFound], 1, 1)
第一,你不能混合那样的东西。如果你有一个查询,它通常需要是一个对目标数据库 运行 的查询。该规则的例外是参数,这是我 认为 您正在尝试做的。
要修复查询,您需要为提供程序使用适当的参数化类型(OLE = ?
、ADO = @Param
、ODBC = ?
),因此它变成像
SubString = SUBSTRING('?', 1, 1)
但这不会是本地 SSIS 人员完成识别变量前导字符的根本任务的方式。
重做
你有一个名为 FileFound
的变量,它包含文件名,你有一个名为 SubString
的变量,你想保存 FileFound
的第一个字符。
我会跳过使用执行 SQL 任务,而是在我们的变量 SubString
对于 2005/2008,右键单击变量和 select 属性。找到两个属性:EvaluateAsExpression
并将其设置为 True,对于 Expression
将其设置为 SUBSTRING(@[User::FileFound], 1, 1)
请注意,我们没有以 A = B 的形式提供显式赋值。相反,我们正在设置我们变量上的 属性 是评估操作的结果。这种方法的美妙之处在于,每次你去访问变量时,它都会评估自己并且你有正确的值。使用您的方法,您需要保留 运行ning 该任务,并可能在需要时复制和粘贴它。
对于 2012+,他们简化了设置表达式的点击路径。您所要做的就是将表达式放入变量 window 的表达式框中,然后自动设置 EvaluateAsExpression。
最后,创建变量对性能没有任何影响。您可以在执行 SSIS 包的任何时候检查变量的值。您可以将它们打印到屏幕上,记录到文件中,随心所欲。您不能做的是查看对象(任务、先例约束等)上存在的表达式的值。如果您对先例约束的逻辑表现得很滑稽——您如何查看执行时的值是什么?你不能。
但是如果您创建第三个变量,ProcessFile
将其设为布尔类型,然后在其上使用表达式 @[User::SubString] == "9"
,看看会发生什么。您可以设置一个断点并确保您的逻辑正确,您可以为任何处理日志发出该值,当逻辑发生变化时(因为我们需要 9 和 7 文件),您可以在一个地方进行更改,所有以我们的新变量 "just work."
综合起来
选项 1
在您的 foreach 枚举器中,您需要一个父任务才能将先例约束添加到实际工作的任务中。在这里我使用了一个序列容器,因为它使用起来不花钱,而且通过这样命名,它的目的是显而易见的。由于 ProcessFile 是布尔值,我使用 @[User::ProcessFile]
的 shorthand 符号作为我的表达式。不用写@[User::ProcessFile] == true
选项 2
由于您从未从全局角度指定要尝试做什么,因此您可以调整 Foreach 循环容器以仅查找所有 9*.* 文件。那么您不需要 SubString 或 ProcessFile 变量。枚举器将拾取的唯一内容是以 9
开头的文件Foreach 文件枚举器。在 Files 部分,您指定要加载的内容。在这里我指定 9*.txt
它将查找所有以 9 开头并以 .txt 扩展名结尾的文件
如果我对你的理解正确,你想要实现的是根据来自先前 ExecuteSQLTask 的某些条件启动循环。
那么它是否归结为这样的事情:
如果是这样,那么这就是我所做的:
a) 获取ResultSet到一个变量中
b) 使用变量并评估它是否为 9
注意:您需要指定两个 (!)= 符号。然后表达式的计算结果为 true 或 false(请参阅上面抱怨此错误的错误)
为了演示,我创建了两个流程来展示条件匹配时会发生什么,一个流程不匹配时会发生什么。
注意:我没有配置Foreach Loop Container.That 是Data Flow Task不绿的原因。它从未被调用过。