本篇文章是Integration Services系列的第五篇,详细内容请参考原文。
在上一篇你学习了如何将更新从源传送到目标。你同样学习了使用基于集合的更新优化这项功能。
回顾增量加载
记住,在SSIS增量加载有三个使用案例:
1、New rows-add rows to the destination that have been added to the source since the previous load.
2、Updated rows-update rows in the destination that have been updated in the source since the previous load.
3、Deleted rows-remove rows from the destination that have been deleted from the source.
在这篇文章中,我们将关注SSIS增量加载功能中的删除行——自从加载到目标之后在源中被移除的行。
删除缺失的行
让我们建立测试条件。关于这一点的思考,就是让行存在于目标表但不存在于源表。类似从源中插入一行到目标,之后再从源中删除此行。打开SSMS和执行下面的T-SQL语句:
use AdventureWorks2012 go insert into dbo.Person(FirstName,MiddleName,LastName,EntityID) values('Andy','Ray','Leonard',99999)
如果执行增量加载删除逻辑就会在源中检测出缺失的行并从目标中删除。此刻我们有一个绝佳的机会测试目标额外一行记录对增量加载逻辑的影响。按下F5键执行SSIS包。检查控制流和数据流任务错误信息。控制流下没有任何错误信息,我的数据流如下所示:
图5.1 数据流任务
这是我所希望的:增量加载运行成功,没有检测到新行或更新行。让我们最后检查下,查找转换操作。点击进度页签搜寻查找转换缓存的记录数:
图5.2 进度中缓存的查找转换记录数
源表(Person.Person)有19972行,查找转换从目标表(dbo.Person)返回19973行,额外的那一行是由查找发现并缓存,但它对于已有的插入和更新数据流逻辑没影响。
在我们往SSIS包中添加新组件前,让我们重命名数据流任务为"Insert and Update Rows"。在控制流画布添加一个数据流任务,并用箭头连接"Apply Staged Updates"执行SQL任务和新数据流任务。重命名数据流任务为"Delete Rows":
图5.3 添加Delete Rows数据流任务
打开Delete Rows数据流任务。添加一个OLE DB源,打开源并配置属性:
->OLE DB连接管理器:127.0.0.1,5377.AdventureWorks2012.sa
->数据访问模式:表或视图
->表或视图的名称:dbo.Person
图5.4 配置OLE DB源
在这个数据流任务中我们使用目标表(dbo.Person)作业源。下一步我们使用一个查找转换来检测行存在于源但没存在于目标(源、目标相对此数据流任务来说)。这和数据流任务中检测新行是完全一样的过程。将一个查找转换拖放到Delete Rows数据流任务,然后连接OLE DB源和查找:
图5.5 添加查找并连接源和查找
打开查找转换编辑器,在常规页面修改指定如何处理无匹配项的行为"将行重定向到无匹配输出":
图5.6 修改无匹配行输出
在连接页面,OLE DB连接管理器选择的是127.0.0.1,5377.AdventureWorks2012.sa。勾选使用SQL查询的结果,并键入如下T-SQL:
select BusinessEntityID As EntityID from Person.Person
我们只需要EntityID识别列。点击列页将可用输入列的EntityID列拖放到可用查找列的EntityID列:
图5.7 查找转换列映射
因为我们配置查找重定向未匹配的行到无匹配输出。如果在源(dbo.Person)和查找表(Person.Person)有没有匹配的行,这些行会被传送到无匹配输出。点击确定按钮关闭查找转换编辑器。
我们怎样完成删除操作呢?我可以通过添加一个OLE DB命令转换(在更新逻辑中操作过)来实现,但是我敢说,你已经知道接下来要做什么操作的。让我们跳过中间部分,直接在Delete Rows数据流任务添加一个OLE DB目标,然后将查找转换的无匹配输出连接到OLE DB目标:
图5.8 添加OLE DB目标
重名称OLE DB目标为StageDeletes,然后右击打开编辑器。和之前一样,在表或视图的名称下拉列表的旁边,点击新建按键。它应该包含下面的DDL命令:
CREATE TABLE [StageDeletes] ( [EntityID] int, [FirstName] nvarchar(50), [LastName] nvarchar(50), [MiddleName] nvarchar(50) )
点击确定关闭创建表窗口(此时它会创建StageDeletes表),点击映射页完成OLE DB目标列映射:
图5.9 OLE DB目标列映射
点击确定关闭OLE DB目标编辑器。和之前一样,我们需要在源表(dbo.Person)应用这个deletes集合。在控制流添加一个执行SQL任务,将Delete Rows数据流任务上的绿箭头连接到新的执行SQL任务:
图5.10 添加执行SQL任务组件
打开执行SQL任务编辑器,修改下面属性:
->Name: Apply Staged Deletes
->Connection: 127.0.0.1,5377.AdventureWorks2012.sa
->SQLStatement:
delete dest from dbo.Person dest join StageDeletes stage on stage.EntityID = dest.EntityID
点击确定按钮关闭执行SQL任务编辑器。让我们先单独测试下这个SSIS任务,右击Apply Staged Deletes执行SQL任务然后点击执行任务:
图5.11 单独执行SQL任务
如果我们配置正确它执行成功。停止BIDS调试器。在基于集合更新逻辑中,我们需要处理StageDeletes表。在每次加载到数据流任务之前我们要先清空它,两次加载中记录一直保持以防我们需要查看。没有必要为它再单独创建执行SQL任务。我们已经有一个Truncate任务。点击打开编辑器,在之前的语句下面添加语句:
Truncate Table StageDeletes
输入SQL查询应该如下所示:
图5.12 输入SQL查询
点击确定按钮关闭输入SQL查询窗口,在关闭执行SQL任务之前,修改它的名称属性为Truncate StageUpdates and StageDeletes。点击确定,按F5执行SSIS包:
图5.13 执行成功的控制流画布
看起来不错,查看Delete Rows数据流任务:
图5.14 Delete Rows数据流任务
到此单独的行已经从目标表(dbo.Person)删除。我们可以在SSMS执行下面语句验证:
use AdventureWorks2012 go select Count(*) As RecCount from dbo.Person where FirstName = 'Andy' and LastName = 'Leonard'
返回0,表明记录已经删除。
总结
这篇文章我们做了很多,完善了我们的第一个SSIS包——增量加载。我们学习了一些入门的ETL测试实例,我们学习了查找转换和执行SQL任务。我们设计创建了一个可重复执行的SSIS包,结合增量加载的概念,它可以每月执行一次,将过去一个月的所有变更应用到目标;也可以每5分钟执行一次将这段时间内的变更应用到目标。