zoukankan      html  css  js  c++  java
  • 【译】第三篇 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包。增量加载有时只加载新行,比如历史每日货币兑换率的表,表中的数据是不会随时间变化的。每一天结束它就固定了。另外源中的数据变更或快或慢,增量加载模式允许你设置一年一次、一分钟一次或任何时间间隔(周期/不周期性)加载数据。只有新行被加载到目标。

  • 相关阅读:
    一点一点学ASP.NET之基础概念——HttpModule
    Repeater为空时显示处理
    数据绑定控件的ItemDataBound事件与System.Data.Common.DbDataRecord
    Fckeditor编辑器添加【行距】
    gridview用法大全(二)
    Web.config自定义节点configSections
    C#中的特性(Attributes)(翻译)
    给程序员的忠告
    项目管理(转载)
    在ASP.NET 2.0中使用样式、主题和皮肤(转载)
  • 原文地址:https://www.cnblogs.com/Uest/p/4748481.html
Copyright © 2011-2022 走看看