3

我在 dtsx 包中有一个数据流,可以处理我需要处理的所有数据。最后,我需要执行一些清理任务。例如,假设以下结构:

我想做的事

如果所有 3 个案例的记录都为真,那么我想运行所有三个 OLE DB 命令。如果记录仅适用于案例 1,则它应该只运行案例 1。

我可以通过多播和 3 个单独的条件拆分(如下所示)来做到这一点,但我希望有一种更清洁的方式。有任何想法吗?

可能的替代方案。 有没有更好的办法?

4

2 回答 2

7

使用多播和三个条件拆分是最容易实现的,也可能是最容易理解的。

设置为具有三个输出的转换的脚本组件可能是下一个最容易实现的 - 但它将涉及大量设置和一定程度的编码。数据流看起来会比较漂亮:

在此处输入图像描述

对于每个输出,确保将其设置Synchronous Input IDNone(以便您可以控制何时创建行);那么您需要在每个输出中复制每个输入列。脚本代码本身将如下所示:

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输出定向到三向多播,其中一个多播输出到三个联合所有转换中的每一个。条件拆分的Cases 1 and 2Cases 2 and 3Cases 1 and 3输出将分别进行双向多播转换(这反过来将馈送到适当的联合全部),而Case 1Case 2输出Case 3将直接转到适当的联合全部。它看起来像这样:

在此处输入图像描述

总而言之,我认为您最初的想法是最简单的,也可能是最好的。

于 2013-03-08T04:25:11.067 回答
1

根据您对 C# 或 VB 的熟悉程度,您可以编写自己的转换,该转换本质上是将多播和条件拆分合二为一。将脚本组件添加到数据流中,它会询问您它是源、转换还是目标。选择转换,添加您的输入和三个输出,然后从那里开始。祝你好运!

于 2013-03-08T03:27:01.143 回答