【译】第三篇 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 ...
- 【译】第二篇 Integration Services:SSIS数据泵
本篇文章是Integration Services系列的第二篇,详细内容请参考原文. 简介SSIS用于移动数据.数据流任务提供此功能.因为这个原因,当介绍SSIS时我喜欢从数据流任务开始.数据流任务的 ...
- 【译】第九篇 Integration Services:控制流任务错误
本篇文章是Integration Services系列的第九篇,详细内容请参考原文. 简介在前面三篇文章,我们创建了一个新的SSIS包,学习了脚本任务和优先约束,并检查包的MaxConcurrentE ...
- 【译】第一篇 Integration Services:SSIS是什么
本篇文章是Integration Services系列的第一篇,详细内容请参考原文. Integration Services是一种在SQL Server中最受欢迎的子系统.允许你在各种数据源之间提取 ...
- 【第三篇】Volley图片加载之NetworkImageView代码分析
在Volley的使用之加载图片讲过使用NetWorkImageView进行图片加载的例子,本文着重讲解NetWorkImageView内部是如何实现的,以及Volley这个控件有什么特性. 1,通 ...
随机推荐
- 笔记之远程桌面服务(RDS)
Windows默认只能有2个用户同时通过RDP进行连接,非常不方便,于是借此机会学习了下Win2012R2的远程桌面配置.以下我把学习过程记录一下: 1. 最开始我觉得只需要安装“Remote Des ...
- [转帖] .net 2.1 是 LTS长期支持版本.
[翻译] .NET Core 2.1 发布 原文: Announcing .NET Core 2.1 我们很高兴可以发布 .NET Core 2.1.这次更新包括对性能的改进,对运行时和工具的改进 ...
- Android 布局类控件
Android提供6种布局类的控件:LinearLayout.TableLayout.GridLayout.FrameLayout.RalativeLayout.AbsoluteLayout 网上搜到 ...
- javascript中boolean类型和其他类型的转换
在javascript中,if语句括号中的表达式返回值可以是任何类型,即:if(a)中的a可以是boolean.number.string.object.function.undefined中的任何类 ...
- POJ1430
这个题目初看上去是一个排列组合题,而实际上……也是一个排列组合题. 题目描述是: Description The Stirling number of the second kind S(n, m) ...
- iOS 数据库sqlite完整增删改查操作
1: 创建数据库表格 1.1 — 表格创建使用一个数据库软件快速创建:软件大小14.3M; 下载地址:http://pan.baidu.com/s/1qWOgGoc; 表格创建-> 打开软件,点 ...
- BZOJ5321 JXOI2017加法(二分答案+贪心+堆+树状数组)
二分答案后得到每个位置需要被加的次数.考虑贪心.从左到右考虑每个位置,将以该位置为左端点的区间按右端点从大到小加进堆.看该位置还需要被加多少次,如果不需要加了就不管,否则取堆顶区间将其选择,BIT实现 ...
- Day22-Django之Form组件验证
1. Django里面的Form专门用来做验证. 用Form创建一个类,把用户发来的数据放到request.POST里面发给这个类,这个类会帮忙做验证. 返回3个结果:是否验证成功了,所有的正确信息, ...
- 获取远程图片的Blob资源
原文地址:http://www.cnblogs.com/JimmyBright/p/7681092.html 思路:js获取远程资源的blob会涉及到跨域的问题,所以需要中转一下,具体是使用php的c ...
- Spring Security OAuth 个性化token
个性化Token 目的 默认通过调用 /oauth/token 返回的报文格式包含以下参数 { "access_token": "e6669cdf-b6cd-43fe-a ...