在数据流任务中,如何使用来自另一个源的值限制行流?
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] <= [MaxDate]
将输出名称设置为插入记录
注意:CONDITIONAL SPLIT 会创建一个带有受限/过滤行的新输出数据流。它不会在现有数据流中创建新列。将此视为从列修改到行修改的数据流输出的转置。只有符合条件的行才会发送到您想要的输出。我假设您只想插入这些记录,所以我将其命名为。您可以选择您喜欢的任何命名约定
注 2:很抱歉没有将更新作为我的原始答案 - 我之前没有使用过 AGGREGATE 转换,所以我不知道它会限制行输出,而不是读取数据流中的值然后将其分配给一个变量。这对于 Microsoft 添加到 SSIS 来说将是一个了不起的转变。看来 ROWCOUNT 和 SCRIPT COMPONENT 转换是唯一能够在数据流中设置包变量值的转换。
【讨论】:
允许的日期需要小于或等于最大日期不等于那你会怎么做? @Unbound 你能合并数据流吗?如果是,则使用 CONDITIONAL SPLIT。 对不起,我不明白这有什么意义。一旦你加入了每条记录的最大日期,就没有必要拆分了。 @Unbound 我已经更新了我的答案。我真的希望微软能够重新审视现有的通用转换并加强它们。这将大大降低软件包的复杂性并简化开发,让开发人员的生活更加轻松,同时促进对免费的优秀工具的采用。 它仍然没有意义。看起来您所描述的是我使用另一个数据流作为解决方法所做的(我也发布了我的解决方法,这是这篇文章的第一个答案)。您的解决方案仍然没有回答如何在单个数据流中一起实现这一目标。请先阅读我和其他人发布的原始问题和答案。以上是关于在数据流任务中,如何使用来自另一个源的值限制行流?的主要内容,如果未能解决你的问题,请参考以下文章