SSIS/Sql 服务器/Visual Studio 2019。
我有一个很大的 csv 文件,里面有很多不确定的数据。我想做的一件事是至少尝试识别相同的连续行并将重复的行剔除。通过“相同”,我想检查 2 个特定的列值 - 名称和公司。
我有一个看起来应该可以工作的流程(鉴于这是我的第一个 SSIS 包和有限的经验),但没有捕捉到顺序重复。我不知道这是否是因为我没有理解条件拆分表达式语法、脚本组件的工作方式,或者包变量更改应该何时/如何从脚本组件生效。没有人抛出错误,但是文件中连续重复的行不会被发送到“拒绝”滑槽。
我创建了两个包变量(lastName 和 lastCompany),初始化为“”。
该流程有一个平面文件源读入,然后是一个条件拆分,其中包括表达式中的其他子句,
... && !(Name == @[User::lastName] && Company == @[User::lastCompany]) &&
这个想法是任何匹配所有子句的东西都将进入“成功”路径,而未通过任何这些检查的行将进入“拒绝”流程。
“成功”流程的下一件事是脚本组件,它执行一些数据规范化并(至少尝试)更新包变量。我为模板找到了另一篇文章。
public override void PostExecute()
{
base.PostExecute();
// I've been trying to debug this and get some output on the VS output window but so far nothing has worked.
// Trace is not showing up in DbgView, FireInformation and FireWarning didn't show up in any of the windows in VS
Trace.WriteLine($"Starting: [{Variables.lastName}|{Variables.lastCompany}], Ending: [{lastName}|{lastCompany}]");
Variables.lastCompany = lastCompany;
Variables.lastName = lastName;
}
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
...
lastName = Row.Name;
lastCompany = Row.Company;
}
我错过了什么
- 包变量的持久性和脚本组件的更新?
- 条件拆分表达式行为?
我的意思是,它看起来应该对我有用,但事实并非如此。
谢谢
SSIS 变量值只能在管道执行
OnPreExecute
的阶段和阶段进行修改。OnPostExecute
在执行期间,它们是静态的。您可以通过使用派生列任务向数据流添加列来验证此行为,并
@[User::lastName]
在脚本任务之后使用添加变量。您会看到第一行和最后一行之间的值永远不会改变。因此,此代码段存在逻辑错误
所以你会怎么做?
最大的挑战当然是你有一个 330M 的行文件。
如果我们只关心顺序重复,那么您设计的脚本任务几乎是正确的,除了尝试分配给 SSIS 变量。相反,您需要将列添加到数据流中,以便后续的条件拆分可以做出合乎逻辑的选择。对于正常工作,我可以将 lastName 和 lastCompany 添加到数据缓冲区。但是,鉴于您将要处理大量数据,您需要争取获得的每一块内存。我将改为在您的脚本任务中执行比较逻辑,并简单地发出一个布尔值,指示该行是否与前一行重复。
我会有一个脚本任务,充当文件源之后的转换。它将作为只读输入列
Company
,Name
并将在输出中添加一个新列,称为IsDuplicate
现在您可以将 Conditional Split 简化为我们列的条件
IsDuplicate
。我将任何匹配的行路由到名为“Sequential Duplicate”的输出,我的默认路径称为“First or non-duplicate rows”。再一次,我试着让我的意图变得显而易见,这样当我必须保持它时,我就可以让我的大脑重新投入到比赛中。这导致我的数据流看起来像