第三篇 Integration Services:增量加载-Adding Rows
本篇文章是Integration Services系列的第三篇,详细内容请参考原文。
增量加载是什么
增量加载仅加载与先前加载差异的。差异包括:
->新增的行
->更新的行
->删除的行
通过它的性质,一个增量加载是可重复执行的,意味着你可以一遍遍的执行而不会损坏数据。更有意思是,加载被设计为执行多次,而不会引起服务器进行不必要的或重复的工作。
在这一篇及接下来的两篇,我们会学习增加加载中的新增、更新、删除行。本篇我们集中在新增上。
To The Keyboard
让我们打开第二篇SSIS数据泵中的My_First_SSIS_Project项目,当你打开项目后,你需要打开解决方案管理器然后双击Package.dtsx来打开SSIS包设计器。
图3.1 打开SSIS包设计器
在图3.1中打开数据流任务编辑器(你可以点击数据流页签,或双击数据流任务,或右击数据流任务然后选择编辑)。一旦打开编辑器,我们可以看到OLE DB源适配器通过数据流路径和OLE DB目标适配器连接:
图3.2 数据流任务下的源和目标
如果你按照第二篇的步骤操作过,那么你从AdventureWorks2012.Person.Person表加载19972行数据到AdventureWorks2012.dbo.Person表。
问题:如果你重新执行SSIS包会发生什么?答案:它会从Person.Person表加载相同的19972行到dbo.Person表。不要不相信我,让我们测试下,在SSMS中执行下面代码:
use AdventureWorks2012
go
select * from [dbo].[Person]
如果脚本返回行数大于19972,说明SSIS包不止执行1次。你可以用下面脚本清除dbo.Person表中的数据:
delete [dbo].[Person]
返回到BIDS然后按F5重新运行SSIS包,当数据加载完成数据流任务如图3.3所示:
图3.3 OLE DB源数据转移到OLE DB目标
返回SSMS并注释掉Delete语句。在Delete语句被选中的情况下,可以通过快捷方式注释语句,按下Ctrl+K,然后按下Ctrl+C键;取消注释,按下Ctrl+K,然后按下Ctrl+U键。
现在dbo.Person表中应该只有19972行记录。你可以用前面的查询语句检查。
如果BIDS调试器还在运行,调试菜单应该如图3.4红粗框所示;此时如果你查看控制流或任务流的工具箱,应该可以看到如图3.4红细框所示的提示信息:
图3.4 运行状态下的调试菜单和工具箱
这是因为BIDS调试器正在运行,可以在图3.4的右上角看到调试菜单中的"启动调试"按钮是灰色/禁用的,因为这个包已经在调试模式下执行。
有几种方式可以停止BIDS调试器。你可以点击调试菜单中的"停止"按钮(图3.4红粗框中);你可以同时按下Shift+F5;你可以点击BIDS->调试->停止调试
图3.5 停止调试
你也可以在包设计器的底部单击“连接管理器”选项卡下方的“链接”:
图3.6 连接管理器下的链接
选择任一方式停止BIDS调试器。
增量加载的目标
在我们开始做一些改变之前,让我们来定义一个增量加载的目标:
1、源新增(new)的数据插入(insert)到目标
2、源修改(changed)的数据更新(update)到目标
3、源移除(removed)的数据从目标中删除(delete)
本篇剩余篇幅将集中讨论第一种情况,源增加新行插入到目标。
检测新行
在我们开始之前,让我们回到SSMS并创建新行测试。通过思考,有一些方式可以建立这个测试:
1、在AdventureWorks2012.Person.Person(源表)加入新行。毕竟,在现实中行会被加到源,然后加载到目标。根据你的设置,这可以简单的完成。
2、从目标删除行
两种方法都能满足测试需求,源中部分记录不存在于目标。这里选择第2种方式,从目标中删除行。让我们在SSMS中执行下面代码:
use AdventureWorks2012
go
delete [dbo].[Person] where MiddleName Is NULL
这条语句将删除dbo.Person表MiddleName列为null的所有记录。当我执行这个语句,可以看到下面信息:
(8499 行受影响)
dbo.Person表中还剩下11473行。我们已经有测试条件,当前源中部分行在目标中不存在。
我们的测试条件存在,我们有新的行加载。增量加载新行要做的第一件事是检测新行。由于我们的源和目标是SQL Server表保存在同一个数据库,我们可以返回SSMS,然后执行一些T-SQL来识别新行。有很多方法可以完成这个。
方法1:使用not in我们可以查找记录在源(Person.Person),没有出现在目标(dbo.Person)。在SSMS的查询窗口执行下面的T-SQL语句:
use AdventureWorks2012
go
select FirstName
,MiddleName
,LastName
,BusinessEntityID
from Person.Person
where BusinessEntityID Not In (select EntityID from dbo.Person)
方法2:使用LEFT JOIN查询检测新行
use AdventureWorks2012
go
select src.FirstName
,src.MiddleName
,src.LastName
,src.BusinessEntityID
from Person.Person src
left join dbo.Person dest
on src.BusinessEntityID = dest.EntityID
where dest.EntityID is null
Breaking a Few Eggs
返回到BIDS中的My_First_SSIS_Project项目,你可能已经猜测到我们需要在OLE DB源和OLE DB目标之间添加组件。因此我们要做的第一件事是,删除数据流路径。右击数据流路径,点击删除:
图3.7 删除数据流路径
一旦删除数据流路径,Person目标适配器将出现一个错误提示(红圈中有一个白X)
图3.8 删除数据流路径后的任务流
这是什么意思?为什么现在出现?因为我们删除了之前配置的数据流路径。记得在第二篇图2.33,我们打开数据流路径编辑器并查看了元数据选项。那里包含了数据流任务传给OLE DB目标(Person)适配器的列信息。数据流路径是数据流任务和目标适配器的一个接口。
我们可以点击视图->错误列表,来查看错误的详细信息:
图3.9 删除数据流路径后的错误信息
OLE DB目标适配器报告缺失的输入列。它无法找到EntityID。但注意其他列也缺少。为什么OLE DB目标适配器没有报其他列的错呢?简单,它不关心有多少列缺失,它知道它需要所有。因此,只要有一个缺少,这就足以抛出错误。
添加查询组件
在数据流画布,OLE DB源和OLE DB目标之间拖放一个查找转换组件。你可能需要将OLE DB目标往下移动腾出空间。在OLE DB源单击,然后单击数据流路径(绿色箭头)并拖动到查找转换:
图3.10 添加查找组件
注意我使用的是SQL Server 2008 R2 Integration Services。在SSIS 2005以后查找转换发生了巨大的变化。以下适用于SSIS 2008和2008 R2。
查找转换所隐含的含义:它在另一个表、视图或查询中查找与流经该变换的行进行匹配。这里有几个关键概念,当我们配置查找时会指出。但一般的想法是"到其他表、视图、或查询,查找在某(些)列是否找到匹配。如果你找到了一个匹配,把这行(或这些行)其他的列返回。"这听起来比较简单,但有一些怪癖:
怪癖1:如果在数据流与查找对象(表、视图、查询)的列上没有找到匹配,查询转换默认会让转换失败
怪癖2:如果在查找对象中找到多条匹配,查询转换只会返回第一条匹配上的。
配置查找转换
双击查找,打开查找转换编辑器。默认显示常规页面,在常规项的顶部是缓存模式配置。
如果你使用的是SSIS2005,你可以在查找转换的属性列表中找到缓存模式选项。缓存模式属性控制实际查找操作何时以及如何发生。
无缓存模式:每行通过转换都会发生查找操作。每当一行传到查找,该转换就在查找对象(表、视图或查询)上执行一个查询;并将任何返回值添加到行中。
完全缓存模式:在数据流任务执行前,查找操作尝试加载查找对象(表、视图或查询)中的所有记录到缓存中。你有没有注意到"尝试"这个词?如果查找对象返回很大的数据集,或者服务器本身内存紧张,查找将会失败。查找缓存holds配置的表、视图或查询的数值。当他们通过转换时缓存中找到的匹配值就添加到行。
在完全缓存模式由于内存紧张导致查找转换失败,你该如何处理呢?一个选择是使用无缓存模式,另一个选择是使用部分缓存模式。还有其他的选择,但已超出本篇文章的范围。
部分缓存模式:当行传入时,转换首先在查找缓存中查找匹配。如果缓存中没有匹配就发生查找操作。匹配的数据加到行和查找缓存。如果另一行通过转换查找相同的匹配列,直接从查找缓存中获取匹配数据。
本例中选择默认配置,完全缓存。查找数据集非常小(19972行)。我会监控这个SSIS包的性能,如果需要就会适当调整。
接着,将"指定如何处理无匹配项的行"更改为"将行重定向到无匹配输出"
图3.11 查找转换编辑器常规页
这是SSIS2008/2008R2查找转换的一个很好的补充。在这个更新版本的查找中,有很多的“绿色”(有效的或非错误)输出,匹配输出和不匹配输出。
点击连接页设置OLE DB连接管理器到127.0.0.1,5377.AdventureWorks2012.sa。类似OLE DB源适配器,我们给连接管理器配置一个接口;同样我们需要选择表或键入查询语句从连接管理器配置的实例.数据库中获取数据。本例中键入下面T-SQL语句:
SELECT [EntityID]
,[FirstName]
,[LastName]
,[MiddleName]
FROM [dbo].[Person]
图3.12 查找转换编辑器连接页
点击列页。在页的右上部分有一些表格形式的表。左边的一个标记为可用输入列。这包含查找转换的输入列列表(记住,查找转换是连接到OLE DB源适配器的输出,这些列就是从那来的)。另一个网格标记可用查找列。这些是连接页上配置的表、视图或查询的列。
在可用输入列上点击EntityID列,然后拖动到可用查找列的EntityID列上。当你松开鼠标时就会在可用输入列的EntityID列和可用查找列的EntityID列之间出现一条直线,类似于join中的on子句,实际就是一个映射关系。
可用查找列旁边有复选框,在网格的顶部有一个选择所有的复选框。If the Lookup Transformation is similar to a Join, the checkboxes are a mechanism for adding columns from the joined table to the SELECT clause.在本例中,不需要检查任何列如图3.13所示:
图3.13 映射列
我们已经配置了查找转换,匹配存在于数据流管道与目标表中的记录。数据流管道中记录来自OLE DB源适配器,是从Person.Person表加载到数据流中。目标表是dbo.Person,我们通过查找转换编辑器中的连接页配置访问。我们配置查找转换通过对比目标表中的EntityID列和源表中的EntityID列。我们配置查找转换处理无匹配项的行时,将行重定向到无匹配的输出。如果在目标和源表中找到匹配行,查找转换将把这些行发送到匹配输出。
点击确定关闭查找转换编辑器。然后点击查找转换拖动其底部的绿数据流路径到OLE DB目标,弹出的对话框中选择"查找无匹配输出"。
图3.14 选择输入输出
让我们回顾一下我们在这里所做的。它能重复,这是一个非常重要的。
为什么选择"查找无匹配输出"?在SSIS2008/2008r2中,查找转换提供内置输出来捕获存在于源表(Person.Person表),但不存在于查找表(dbo.Person表)——查找无匹配输出。
让我们看一下数据流任务,检查添加查找转换的影响。右键单击OLE DB源适配器和查找转换之间的数据流路径,然后单击“编辑”:
图3.15 编辑数据流路径
当打开数据流路径编辑器,点击元数据页。路径数据元如图3.16所示:
图3.16 源和查找之间的数据流路径编辑器
这些列来自OLE DB源将进入到查找转换。关闭这个数据流路径编辑器。右击查找和OLE DB目标之间的数据流任务,然后选择编辑打开另一个数据流路径编辑器:
图3.17 查找和目标之间的数据流路径编辑器
它们是相同的!查找转换的无匹配输出是查找转换输入的一个拷贝。如果我们没有找到匹配,我们希望通过查找转换的无匹配输出传送所有的数据列给后续操作。关闭数据流路径编辑器。
当你完成,数据流任务画布将如图3.18所示:
图3.18 数据流任务画布
让我们测试,按F5。你应该能看到绿色窗体:
图3.19 第一次执行SSIS包
我们刚刚加载了8499行新数据。这8499行新数据来自哪里。是否记得:为了模拟新行,我们从dbo.Person表中删除8499行。我们只是重新加载它们。
现在你可以做些有趣的事情,点击调试菜单中的重新启动按钮:
图3.20 重新启动SSIS包
点击重新启动按钮,SSIS包会停止调试并重新启动调试。这次,注意查找转换在目标表中找到了源表中的所有行:
图3.21 第二次执行SSIS包
因为查找转换找到了所有匹配行,它们不会被发送到无匹配输出。
总结
我们已经完成了一组目标。首先,我们建立了一个加载器,只将源表中的新行添加到目标表。其次,我们所建的加载器是可重复执行的,它并不是将一堆复本复制到目标。
在离开这个主题之前,我想强调的是,你已经建立了一个有用的SSIS包。生产环境中有很多类似加载数据的SSIS包。增量加载有时只加载新行,比如历史每日货币兑换率的表,表中的数据是不会随时间变化的。每一天结束它就固定了。另外源中的数据变更或快或慢,增量加载模式允许你设置一年一次、一分钟一次或任何时间间隔(周期/不周期性)加载数据。只有新行被加载到目标。
第三篇 Integration Services:增量加载-Adding Rows的更多相关文章
- 【译】第三篇 Integration Services:增量加载-Adding Rows
本篇文章是Integration Services系列的第三篇,详细内容请参考原文. 增量加载是什么增量加载仅加载与先前加载差异的.差异包括:->新增的行->更新的行->删除的行通过 ...
- 第五篇 Integration Services:增量加载-Deleting Rows
本篇文章是Integration Services系列的第五篇,详细内容请参考原文. 在上一篇你学习了如何将更新从源传送到目标.你同样学习了使用基于集合的更新优化这项功能.回顾增量加载记住,在SSIS ...
- 第四篇 Integration Services:增量加载-Updating Rows
本篇文章是Integration Services系列的第四篇,详细内容请参考原文. 回顾增量加载记住,在SSIS增量加载有三个使用案例:1.New rows-add rows to the dest ...
- 【译】第五篇 Integration Services:增量加载-Deleting Rows
本篇文章是Integration Services系列的第五篇,详细内容请参考原文. 在上一篇你学习了如何将更新从源传送到目标.你同样学习了使用基于集合的更新优化这项功能.回顾增量加载记住,在SSIS ...
- 【译】第四篇 Integration Services:增量加载-Updating Rows
本篇文章是Integration Services系列的第四篇,详细内容请参考原文. 回顾增量加载记住,在SSIS增量加载有三个使用案例:1.New rows-add rows to the dest ...
- 【第三篇】Volley图片加载之NetworkImageView代码分析
在Volley的使用之加载图片讲过使用NetWorkImageView进行图片加载的例子,本文着重讲解NetWorkImageView内部是如何实现的,以及Volley这个控件有什么特性. 1,通 ...
- UITableView个人使用总结【前篇-增量加载】
UITableView现在边整边总结. 预计分两个部分,第一个部分主要是对UITableView本身属性的学习.第二个部分可能会是加上一个编辑按钮以及对列表的操作. 今天先学习第一部分. 第一部分,我 ...
- 第六篇 Integration Services:初级工作流管理
本篇文章是Integration Services系列的第六篇,详细内容请参考原文. 简介在前几篇文章中,我们关注使用增量加载方式加载数据.在本篇文章,我们将关注使用优先约束管理SSIS控制流中的工作 ...
- 【译】第六篇 Integration Services:初级工作流管理
本篇文章是Integration Services系列的第六篇,详细内容请参考原文. 简介在前几篇文章中,我们关注使用增量加载方式加载数据.在本篇文章,我们将关注使用优先约束管理SSIS控制流中的工作 ...
随机推荐
- RTO & RPO
作者:王文洋链接:https://www.zhihu.com/question/30753842/answer/49334210来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...
- 【iHMI43 4.3寸液晶模块】demo例程(库函数版)发布
一.说 明: 1.iHMI43 演示程序(0.15版)的库函数版:此程序仅用于 iHMI43 液晶模块: 2.各外设驱动均使用库函数模式操作,其他程序可参考本例子修改: 3.如果下载不进去,请重新配置 ...
- SQL Server访问MySql
使用环境:操作系统:window7数据库:SQL Server2005.MySql5.01.在安装了SQL Server的服务器上安装MySql的ODBC驱动:下载链接:http://dev.mysq ...
- svn vs git
SVN和Git比较,哪个好用,适用? GIT和SVN之间的五个基本区别 话说Git的区别
- anisotropy texture filtering
http://www.extremetech.com/computing/51994-the-naked-truth-about-anisotropic-filtering 1. 为什么在纹理采样时需 ...
- PHP 防止表单重复提交
原理是:首先在表单页生成一个 随机不重复的 token(可以利用时间戳),把 token 的值分别存入 session 和 表单的隐藏域:当提交表单的时候,在接收页对比传递过来的 token 和ses ...
- hiho48 : 欧拉路·一
时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho最近在玩一个解密类的游戏,他们需要控制角色在一片原始丛林里面探险,收集道具,并找到最后的宝藏.现在他们控制的 ...
- delphi 创建DBASE和FOXPRO两类DBF数据文件的差异
delphi 创建DBASE和FOXPRO两类DBF数据文件的差异,主要有几点: 1.创建方法不同 DBASE的创建方法: Self.Table1.Close; Self.Table1.Active ...
- Lazarus中TScreen类使用介绍
描述:虚拟屏幕(桌面)可以包含多个物理显示器.Screen对象是鼠标指针.字体.窗体. 对于Delphi兼容的(不可见)DataModules也被列出了. 同时也追踪当前活动窗体窗体.控件和指针. S ...
- 使用微信JS-SDK 实现 自定义 分享 功能
微信PC端点击页面,转发给朋友.