在数据流任务中,如何使用来自另一个源的值限制行流?

Posted

技术标签:

【中文标题】在数据流任务中,如何使用来自另一个源的值限制行流?【英文标题】:In a data flow task, how do I restrict rows flowing using a value from another source? 【发布时间】:2019-09-05 07:29:32 【问题描述】:

我有一个带有许多选项卡的 Excel 表。假设一个称为 wsMain,另一个称为 wsDate。

在我的数据流转换中,我能够成功地将数据从 wsMain 加载到我的表中。

现在我必须更新这个转换,我必须从工作表 wsDate 中获取最大日期,并且只从日期小于等于 wsDate 中的最大日期的 wsMain 加载数据(这是唯一可用的列) .

所以我发现我需要创建一个新的 Excel 连接管理器来从 wsDate 读取数据,并且我已经使用聚合转换来获取最大日期。

现在的问题是如何使用这个日期来限制来自 wsMain 的行?

我从下面的链接了解到,您可以将值存储在变量中,但接下来我该怎么做?: SSIS set result set from data flow to variable

我尝试过使用合并连接,但不确定我是否正确。

这是现在的样子:

【问题讨论】:

【参考方案1】:

我无法实现上述目标,但很想知道这是否可能。作为一种解决方法,我创建了一个单独的数据流,其中我将值存储在一个变量中,然后使用 conditional split 中的变量来过滤所需的行:

这是我编写变量的分步指南: https://www.proteanit.com/2008/12/11/ssis-writing-to-a-package-variable-in-a-dataflow/

【讨论】:

【参考方案2】:

您可以先获取wsDate列的最大值,将其用作过滤器,以避免将不必要的记录引入数据流中,这些记录将被条件拆分丢弃。该过程的概述如下。我还建议确认所有相关列的数据类型。

创建一个 SSIS DateTime 变量并将其命名为具有描述性的名称,例如 MaxDate

在当前任务之前使用 Excel 源组件创建一个数据流任务。使用数据访问模式的 SQL 命令选项并输入 SQL 语句以返回 wsDate 列的最大值。在以下示例中,ExcelSource 是您从中提取的工作表的名称。我建议也使用 Excel 源上的 Preview 按钮确认查询。

在 Excel 源代码之后添加一个脚本组件(不是任务)。在脚本组件主页的ReadWriteVariables 字段中添加MaxDate 变量。在 Inputs and Outputs 窗格中,将 Excel 源中的输出列添加为具有 ReadOnly 使用类型的输入列。示例 C# 代码如下。请注意,变量只能在PostExecute 方法中写入。 Input0_ProcessInputRow 方法对通过的每一行调用一次,但是在这种情况下只有一行。在以下代码中,MaxExcelDate 是 Excel 源中输出列的名称。

在从 Excel 导入记录的数据流任务中的 Excel 源组件上,将数据访问模式更改为 SQL 命令并输入 SQL 语句以返回日期小于或等于最大wsDate 值。这是最后一个示例,? 是参数的占位符。输入此 SQL 后,单击Parameters 按钮,并在Parameters 字段中选择Parameter0,在Variables 字段中选择MaxDate 变量,并选择Input 的方向。然后可以删除条件拆分,因为这些记录现在将被过滤掉。

Excel MAX wsDate 选择:

SELECT MAX(wsDate) AS MaxExcelDate FROM ExcelSource

C# 脚本组件:

DateTime maxDate;
public override void PostExecute()

    base.PostExecute();
    Variables.MaxDate = maxDate;

public override void Input0_ProcessInputRow(Input0Buffer Row)

    maxDate = Row.MaxExcelDate;

带有日期过滤器的 Excel 命令:

SELECT 
    Column1,
    Column2,
    Column3
FROM ExcelSheet 
WHERE DateColumn <= ?

【讨论】:

【参考方案3】:

是的,这是可能的。在数据流中,您需要确定您已经拥有的最大日期。接下来,您需要 MERGE JOIN 合并日期列上的两个数据流。从那里,您将把它输入到条件分割中,并在日期列匹配 [即!ISNULL()] 与不匹配 [即 ISNULL()] 的位置进行分割。在您的情况下,您只需要匹配项。不匹配的将被忽略。

注意:如果您在只有一个日期(即 MaxDate)可加入的 MERGE JOIN 上使用 INNER JOIN,那么这将为您处理行过滤。您将不需要条件拆分。

欢迎来到 ETL。

更新

SSIS 的 MERGE JOIN 仅在 EQUAL 操作上执行连接,而不是 LESS THAN 和 GREATER THAN 操作,这真的很痛苦。您需要分离数据流。

    使用脚本组件扫描 Excel 文件中的 MAX 日期,并将该值分配给 SSIS 中的包变量。或者,您可以在 SQL Server 中创建一个日期表,然后在 SSIS 中使用执行 SQL 命令从表中检索 MAX Date 并将该值分配给包变量 修改现有数据流以完全删除 Excel 日期文件的读取。然后添加一个 DERIVED COLUMN 转换并添加一个新列,该列映射到 SSIS 中存储 MAX 日期的包变量。您可以将派生列名称命名为“MaxDate” 使用以下 CONDITION 逻辑添加条件拆分转换:[AsOfDt] &lt;= [MaxDate] 将输出名称设置为插入记录

注意:CONDITIONAL SPLIT 会创建一个带有受限/过滤行的新输出数据流。它不会在现有数据流中创建新列。将此视为从列修改到行修改的数据流输出的转置。只有符合条件的行才会发送到您想要的输出。我假设您只想插入这些记录,所以我将其命名为。您可以选择您喜欢的任何命名约定

注 2:很抱歉没有将更新作为我的原始答案 - 我之前没有使用过 AGGREGATE 转换,所以我不知道它会限制行输出,而不是读取数据流中的值然后将其分配给一个变量。这对于 Microsoft 添加到 SSIS 来说将是一个了不起的转变。看来 ROWCOUNT 和 SCRIPT COMPONENT 转换是唯一能够在数据流中设置包变量值的转换。

【讨论】:

允许的日期需要小于或等于最大日期不等于那你会怎么做? @Unbound 你能合并数据流吗?如果是,则使用 CONDITIONAL SPLIT。 对不起,我不明白这有什么意义。一旦你加入了每条记录的最大日期,就没有必要拆分了。 @Unbound 我已经更新了我的答案。我真的希望微软能够重新审视现有的通用转换并加强它们。这将大大降低软件包的复杂性并简化开发,让开发人员的生活更加轻松,同时促进对免费的优秀工具的采用。 它仍然没有意义。看起来您所描述的是我使用另一个数据流作为解决方法所做的(我也发布了我的解决方法,这是这篇文章的第一个答案)。您的解决方案仍然没有回答如何在单个数据流中一起实现这一目标。请先阅读我和其他人发布的原始问题和答案。

以上是关于在数据流任务中,如何使用来自另一个源的值限制行流?的主要内容,如果未能解决你的问题,请参考以下文章

如何提供 Apache Flink DataStream

同源策略

同源策略

通信类

同源策略形象解读

关于Jsonp 跨域