首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >SSIS -仅当第一个数据集中不存在关键字时才合并结果

SSIS -仅当第一个数据集中不存在关键字时才合并结果
EN

Stack Overflow用户
提问于 2019-03-21 01:38:51
回答 3查看 1.3K关注 0票数 2

我正在尝试将两个库存来源与SSIS结合起来。第一个包含来自我们新系统的库存信息,而第二个包含旧数据。我可以很好地从来源获取数据。

两个数据集具有相同的列,但是如果第一个数据集中不存在该记录的ItemCode值,我只想从第二个数据集中获得结果。

要实现这一点,我需要使用哪种转换?

编辑-这是我到目前为止在我的数据流中的内容。

我需要向Extract Legacy Item Data源添加一个转换,这样它就会删除Extract New Item Data源中已经存在其商品代码的记录。

这两个源位于不同的服务器上,因此我无法通过修改查询来进行解析。我还希望避免运行在Extract New Item Data源代码中运行的相同查询。

EN

回答 3

Stack Overflow用户

发布于 2019-03-21 02:22:50

首先,考虑到您正在使用SQL Server Destination,我建议阅读来自SSIS专家@billinkc的以下答案:

我将提供不同的方法来实现此目标:

(1)使用查找转换

  1. 您应该添加一个数据流任务,您可以在其中添加第二个库存(遗留)作为源
  2. 添加一个查找转换,您可以在其中选择第一个库存来源作为查找表。
  3. 在查找转换中将源和查找表与ItemCode
  4. 映射从下拉列表中选择Redirect rows to no match output
  5. 使用查找不匹配输出获取所需行(在第一个库存源中找不到)

你可以参考下面的链接,它包含了一个分步教程。

帮助链接

  • UNDERSTAND SSIS LOOKUP TRANSFORMATION WITH AN EXAMPLE STEP BY STEP

SSIS的旧版本

如果您使用的是旧版本的SSIS,那么您将找不到Redirect rows to no match output下拉列表。相反,您应该转到Lookup Error输出,为No Match情况选择Redirect Row选项,并使用错误输出来获取所需的行。

(2)使用链接服务器

在第二个清单上,创建能够连接第一个服务器的链接服务器。现在,您可以使用SQL命令,该命令仅选择在第一个源中未找到的行:

代码语言:javascript
运行
复制
SELECT *
FROM Inverntory2
WHERE NOT EXISTS (SELECT 1 FROM <Linked Server>.<database>.<schema>.Inverntory1 Inv1 WHERE Inverntory2.ItemCode = Inv1.ItemCode)

(3)临时表+合并、合并连接、联合所有转换

在每个源SQL命令上,添加一个包含源id (1,2)的固定值列,例如:

代码语言:javascript
运行
复制
SELECT *, 1 as SourceID FROM Inventory

您可以使用上面列出的转换之一将两个源合并到一个目标中,然后添加第二个数据流任务,以便根据ItemCode列将不同的数据从临时表导入到目标中,例如:

代码语言:javascript
运行
复制
SELECT * FROM (
       SELECT *, ROW_NUMBER() OVER(PARTITION BY ItemCode ORDER BY SourceID) rn
       FROM StagingTable ) s
Where s.rn = 1

然后,它将返回SourceId =1中的所有行以及SourceId = 2中的新行

要了解有关合并、合并连接和联合所有转换的更多信息,您可以参考以下链接之一:

注意:检查@userfl89提供的答案,它包含了关于使用合并连接转换的非常详细的信息,并且它描述了另一种可以提供帮助的方法。现在,您必须测试哪种方法适合您的需求。祝好运

票数 0
EN

Stack Overflow用户

发布于 2019-03-21 17:02:42

如果两个源类型都是SQL数据库,并且它们存储在同一台服务器上,则可以使用SQL命令作为源来实现此目的:

代码语言:javascript
运行
复制
SELECT Inverntory2.*
FROM Inverntory2 LEFT JOIN Inverntory1
     On Inverntory2.ItemCode = Inverntory1.ItemCode
WHERE Inverntory1.ItemCode IS NULL

代码语言:javascript
运行
复制
SELECT *
FROM Inverntory2
WHERE NOT EXISTS (SELECT 1 FROM Inverntory1 WHERE Inverntory2.ItemCode = Inverntory1.ItemCode)
票数 0
EN

Stack Overflow用户

发布于 2019-03-21 23:33:26

下面是一个这样的例子。使用SQL Server目标可以很好地工作,但是这只允许加载到本地SQL Server实例,这是您将来可能需要考虑的事情。虽然Lookup通常执行得更好,但合并联接在某些情况下可能是有益的,例如在数据流中引入了许多额外的列时,就像对数据集所做的那样。看起来@Hadi已经介绍了如何使用Lookup来实现这一点,因此您可能希望在模拟prod的非生产环境中测试这两种方法,然后评估结果以确定更好的选项。

  • 首先创建一个临时表,它是其中一个表的精确克隆。这两个表都可以工作,因为它们具有相同的定义。请确保登台中的所有列都允许空值。
  • 通过截断或删除登台表,然后创建该表,从而在数据流任务之前添加执行SQL任务以清除登台表。
  • 是因为ItemCode在每个OLE DB源中对此列进行唯一排序。如果您尚未在两个OLE DB源中将“数据访问模式”更改为“SQL”命令,请为ItemCode添加一个ORDER BY子句。为此,请右键单击“OLE DB源”并转至“SQL显示高级编辑器”>“输入和输出属性”“”>“OLE DB Source Output”>“Output Column”>,然后选择“ItemCode”并将SortKeyPosition属性设置为1(假设您在SQL statement).
  • Next中执行了ASC source在数据流任务中添加合并联接。这要求两个输入都要排序,这就是输入现在排序的原因。您可以使用任何一种方法来完成此操作,但对于此示例,请使用仅当ItemCode 不存在时才使用的OLE DB源作为合并联接左输入。使用左外部联接和ItemCode列作为联接键,方法是在图形用户界面中拖动一条线将它们连接起来。当两个数据集中存在相同的ItemCode时,通过在合并联接编辑器中选中列旁边的复选框,添加要使用的OLE DB源中的所有列(从我可以断定这是Extract New Item Data,如果不是,请调整它)。使用有助于区分这些别名的输出别名前缀,例如X_ItemCode表示匹配的行。
  • 在合并联接之后添加条件拆分。这是根据是否找到X_ItemCode来划分记录。对于第一个输出的表达式,使用ISNULL函数来测试是否存在来自左外部联接的匹配。例如,ISNULL(X_ItemCode) != TRUE表示ItemCode确实存在于两个数据集中。您可以将此输出行称为匹配行。默认输出将包含不匹配项。为了便于区分,您可以将默认输出重命名为Non-Matching Rows.
  • Connect Matching Rows.
  • Connect output To the destination table。在此example.
  • Back中,当两个数据集中都存在X_时,仅映射与要使用的源的匹配的行的列,即数据流中的另一个SQL Server目标中的X_前缀行,并将输出的不匹配的行输出连接到此任务,使用从不匹配的行映射的所有列,在包中的控制流上添加另一个数据流任务之后添加另一个数据流任务。将临时表用作OLE DB源,将目标表用作SQL Server目标。这里不需要排序。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55267034

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档