具有优先约束的文件名子字符串 - SSIS

时间:2016-03-14 22:52:21

标签: sql sql-server ssis sql-server-data-tools

我通过SQL任务使用基于表达式的约束来确定我的For Each File循环是否将平面文件添加到我的数据库对象。这基于平面文件名的第一个字符的值。到目前为止采取的步骤:

添加了一个带有表达式SubString = SUBSTRING(@[User::FileFound], 1, 1)的执行SQL任务。

将结果集设置为SingleRow。我设置的ResultSet的结果名称为SubString,变量名称为User::SubString

然后,对于我的优先约束,我使用了@[User::SubString] = "9"的表达式,该表达式使用“测试”按钮成功验证。

但是我将以下错误文本打印到屏幕上:

[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
------------------------------

感觉我现在正走在正确的轨道上,但只是遗漏了一些东西。

由于

2 个答案:

答案 0 :(得分:1)

有些事情看似错误。

为您的先例约束

  

表达式" @ [User :: SubString] =" 9""必须评估为真或假

您正在尝试使用赋值运算符,=不测试相等==

在执行SQL任务中,表明您有此片段

SubString = SUBSTRING(@[User::FileFound], 1, 1)

一,你不能混合这样的东西。如果您有查询,则通常需要是针对目标数据库运行的查询。该规则的例外是参数,这是我认为您正在尝试做的事情。

要修复查询,您需要为提供商使用适当的参数化类型(OLE = ?,ADO = @Param,ODBC = ?),以便它变得像

SubString = SUBSTRING('?', 1, 1)

但这不是本地SSIS人员如何完成识别变量主要字符的根本任务。

做完

您有一个名为FileFound的变量,其中包含文件名,您有一个名为SubString的变量,您希望保留FileFound的第一个字符。

我会跳过使用执行SQL任务,而是在变量SubString

中完成工作

对于2005/2008,右键单击“变量”并选择“属性”。找到两个属性:EvaluateAsExpression并将其设置为True,Expression将其设置为SUBSTRING(@[User::FileFound], 1, 1)请注意,我们不会以A = B的形式提供明确的分配。相反,我们我们将变量的属性设置为评估操作的结果。这种方法的美妙之处在于,每次访问变量时,它都会自我评估并且您具有正确的值。使用您的方法,您需要继续运行该任务,并可能在需要时复制和粘贴它。

对于2012年以上,他们简化了设置表达式的点击路径。您所要做的就是将表达式放在Variable窗口的Expression框中,并自动设置EvaluateAsExpression。

最后,创建变量不会让您失去性能。您可以在执行SSIS包的任何时刻检查变量的值。您可以将它们打印到屏幕,登录到文件,无论您想要什么。你不能做的是查看对象上存在的表达式的值(任务,先例约束等)。如果您对先例约束的逻辑表现得很有趣 - 您如何看待并查看执行点的值是什么?你不能。

但是如果你创建第三个变量,ProcessFile使它成为布尔类型,然后在其上使用表达式@[User::SubString] == "9",看看会发生什么。您可以设置断点并确保逻辑正确,您可以为任何处理日志发出该值,并且当逻辑发生更改时(因为我们需要9和7个文件),您可以在一个地方进行更改并且所有键入我们新变量值的地方"只是工作。"

全部放在一起

enter image description here

选项1

在foreach枚举器中,您需要一个父任务才能为实际工作的任务添加先例约束。在这里,我使用了一个序列容器,因为它不需要任何费用,并且通过命名它,它的目的是显而易见的。由于ProcessFile是boolean,我使用@[User::ProcessFile]的简写表示法作为我的表达式。无需撰写@[User::ProcessFile] == true

选项2

由于您从未从大图片角度指定了您尝试做的事情,因此您可以调整Foreach循环容器以查找所有9 *。*文件。那么你不需要SubString或ProcessFile变量。枚举器唯一能找到的就是以9开头的文件

Foreach文件枚举器。在 Files 部分中,您可以指定要加载的内容。在这里,我指定9*.txt,它将找到所有以9开头并以.txt扩展名结尾的文件

enter image description here

答案 1 :(得分:1)

如果我确实理解你想要实现的目的,那就是根据以前的ExecuteSQLTask中的某些条件启动一个循环。 所以它归结为这样的事情: enter image description here

如果是这样,那么我就是这样做的:

a)将ResultSet放入变量中 enter image description here

b)使用变量并评估它是否为9 enter image description here
注意:您需要指定两个(!)=符号。然后表达式的计算结果为true或false(请参阅上面的错误,抱怨这个错误)

对于演示,我创建了两个流程来显示条件匹配时会发生什么,以及不匹配时会发生什么。
注意:我没有配置Foreach循环容器。这就是数据流任务不是绿色的原因。它从未被称为。 enter image description here