【发布时间】:2013-03-08 12:32:29
【问题描述】:
我在 dtsx 包中有一个数据流,用于处理我需要处理的所有数据。最后,我需要执行一些清理任务。例如,假设以下结构:
如果所有 3 个案例的记录都为真,那么我想运行所有三个 OLE DB 命令。如果记录仅适用于案例 1,那么它应该只运行案例 1。
我可以通过多播和 3 个单独的条件拆分(如下所示)来做到这一点,但我希望有一种更简洁的方式。有什么想法吗?
【问题讨论】:
标签: sql-server ssis
我在 dtsx 包中有一个数据流,用于处理我需要处理的所有数据。最后,我需要执行一些清理任务。例如,假设以下结构:
如果所有 3 个案例的记录都为真,那么我想运行所有三个 OLE DB 命令。如果记录仅适用于案例 1,那么它应该只运行案例 1。
我可以通过多播和 3 个单独的条件拆分(如下所示)来做到这一点,但我希望有一种更简洁的方式。有什么想法吗?
【问题讨论】:
标签: sql-server ssis
使用一个多播和三个条件拆分是最容易实现的,也可能是最容易理解的。
将脚本组件设置为具有三个输出的转换可能是下一个最容易实现的 - 但它会涉及大量设置和一定程度的编码。数据流看起来会比较漂亮:
对于每个输出,确保将Synchronous Input ID 设置为None(以便您可以控制何时创建行);那么您需要在每个输出中复制每个输入列。脚本代码本身将如下所示:
public override void IncomingRows_ProcessInputRow(IncomingRowsBuffer Row)
{
if (Case1Logic(Row))
{
Case1OutputBuffer.AddRow();
Case1OutputBuffer.ProductId = Row.ProductID;
Case1OutputBuffer.Name = Row.Name;
// etc. for all columns
}
if (Case2Logic(Row))
{
Case2OutputBuffer.AddRow();
Case2OutputBuffer.ProductId = Row.ProductID;
Case2OutputBuffer.Name = Row.Name;
// etc. for all columns
}
if (Case3Logic(Row))
{
Case3OutputBuffer.AddRow();
Case3OutputBuffer.ProductId = Row.ProductID;
Case3OutputBuffer.Name = Row.Name;
// etc. for all columns
}
}
private bool Case1Logic(IncomingRowsBuffer Row)
{
// Whatever the Case 1 logic involves
}
private bool Case2Logic(IncomingRowsBuffer Row)
{
// Whatever the Case 2 logic involves
}
private bool Case3Logic(IncomingRowsBuffer Row)
{
// Whatever the Case 3 logic involves
}
当人们决定要更改列时,保持更新很有趣!
如果这对您来说还不够复杂,您可以编写自己的自定义转换。关于如何做到这一点的血腥细节在MSDN;只需说将涉及很多更多代码。对于 SSIS 如何处理缓冲区管理,您还将了解比您想知道的更多,这反过来可以解释为什么开箱即用的条件拆分不允许您将同一行发送到多个输出。
最后,如果您想要一个看起来非常难看的解决方案,同时也是一场维护噩梦,请尝试构建一个条件拆分,每个案例组合都有一个输出。在您的每个 OLE 目标前面放置一个 Union All 转换。将Cases 1, 2 and 3 输出定向到三路多播,其中一个多播输出到三个Union All 转换中的每一个。条件拆分的Cases 1 and 2、Cases 2 and 3 和Cases 1 and 3 输出将分别进行双向多播转换(这反过来将提供适当的Union All),而Case 1、Case 2 和@987654333 @ 输出将直接转到适当的 Union All。它看起来像这样:
总之,我认为您最初的想法是最简单的,也可能是最好的。
【讨论】:
根据您对 C# 或 VB 的熟悉程度,您可以编写自己的转换,该转换本质上是将多播和条件拆分合二为一。将脚本组件添加到数据流中,它会询问您它是源、转换还是目标。选择转换,添加您的输入和三个输出,然后从那里开始。祝你好运!
【讨论】: