zoukankan      html  css  js  c++  java
  • SSIS中的脚本—脚本组件

    脚本组件提供另外一种在SSIS中使用脚本的方法,它只能在Data Flow中使用,不能在Control Flow中使用,它用来提供数据,接收数据,转换数据。下面是三种类型:


        数据源类型:用来提供数据源,可以定义输出类型,使用脚本填充数据。了个典型的例子是使用脚本来读取复杂的文件,XML,或者更加过时的COBOL等等不能产生平面文件的文件
        数据目的类型:用来将数据填充到Excel,或者平面文件,或者将文件批处理到大型机上
        转换型:用来接收数据,产生新的转换数据,当SSIS提供的组件不能满足需求的时候使用

      

    使用脚本组件

    这里我们举例说明如何创建和使用脚本组建,我们处理一个文件,按照需求清洗文件中的数据。符合要求的数据将会被送到合适的表中,反之被送到另外一个表中。
    我们处理一个包含联系人信息的文件,数据库对文件数据有一些验证要求,不符合验证标准的数据将会被送到另外一个表中人工处理。
    使用下面的代码来建立这两个表:

    CREATE TABLE dbo.Contacts
    (
    ContactID
    int NOT NULL IDENTITY (1, 1),
    FirstName
    varchar(50) NOT NULL,
    LastName
    varchar(50) NOT NULL,
    City
    varchar(25) NOT NULL,
    State
    varchar(15) NOT NULL,
    Zip
    char(10) NULL
    )
    ON [PRIMARY]
    CREATE TABLE dbo.ContactsErrorQueue
    (
    ContactErrorID
    int NOT NULL IDENTITY (1, 1),
    FirstName
    varchar(50) NULL,
    LastName
    varchar(50) NULL,
    City
    varchar(50) NULL,
    State
    varchar(50) NULL,
    Zip
    varchar(50) NULL
    )


    两个表的区别是ContactsErrorQueue表中的数据类型都是varchar(50),并且可为空。下载Contacts.dat文件,这个文件中的数据边界分割位置如下:

    Field       Starting Position
    FirstName          1
    LastName          10
    City                   25
    State                 43
    Zip                    51

     

    数据的个数类似下面

    Jason     Gerard         Jacksonville      FL      32276-1911

    Joseph    McClung        JACKSONVILLE      FLORIDA 322763939

    Andrei    Ranga          Jax               fl      32276

    Chad      Crisostomo     Orlando           FL      32746

    Andrew    Ranger         Jax               fl

     

    新建一个package命名为ScriptComponent,拖放一个Flat File source,双击打开编辑界面,点击新建连接,打开文件连接管理界面,将文件连接命名为Contacts Mainframe Extract。点击浏览选择Contacts.dat文件,选择文件格式为Fixed Width,设置行宽为62,按照上面标设置列边界。点击Advance,按照上表为数据列命名。最后预览数据如下图1:

    图1

      

    新建一个package命名为ScriptComponent,拖放一个Flat File source,双击打开编辑界面,点击新建连接,打开文件连接管理界面,将文件连接命名为Contacts Mainframe Extract。点击浏览选择Contacts.dat文件,选择文件格式为Fixed Width,设置行宽为62,按照上面标设置列边界。点击Advance,按照上表为数据列命名。最后预览数据如下图2:

    图2

      

    将Flat File Source和Script Component连接起来,双击script component打开编辑界面,点击Input Column标签,可以看到在Input Name下拉列表中默认选择Input 0,如果有其他输入的话,这里可以选择其他的输入,如图3。

    图3

      

    选择所有的输入列。点击Input and Output标签,查看输入列和输出列的属性。展开Output 0,选中Output Columns,点击Add Column按钮添加新列,命名为GoodFlag,修改数据类型为Boolean[DT_BOOL]。
    点击Edit Script按钮打开编解界面,这里的代码和Script task有所不同

    ' Microsoft SQL Server Integration Services Script Component

    ' Write scripts using Microsoft Visual Basic 2008.

    ' ScriptMain is the entry point class of the script.

     

    Imports System

    Imports System.Data

    Imports System.Math

    Imports Microsoft.SqlServer.Dts.Pipeline.Wrapper

    Imports Microsoft.SqlServer.Dts.Runtime.Wrapper

     

    Public Class ScriptMain

        Inherits UserComponent

     

        Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)

            '

            ' Add your code here

            ''

            Return

     

        End Sub

     

    End Class

    引入的命名空间有所不同,添加了两个新的命名空间Pipeline和Wrapper。ScriptMain类继承UserComponent。没有Mian()方法了,而是新的方法Input0_ProcessInputRow,它的参数Input0Buffer是一个自动产生的类,它包含所有的输入输出列,都有强类型的属性。
    这里一共产生了3个源文件:BufferWrapper,ComponentWrapper,ScriptMain。BufferWrapper包含自动产生的代码缓冲,在这个例子中只有一个类Input0Buffer,它是自动产生的每次打开都回自动覆盖,所以不要修改这里的代码。文件ComponentWrapper中包含类UserComponent,主要的功能包含在类ScriptMain中。


    要进行的验证有:
    • 除了字段zip,所有的字段都要求非空
    • Zip的格式要求DDDDD-DDDD或 DDDD,这里D是一个0至9的数字,如果前5个数字验证成功,后面没有成功则截取前5个,后面的舍弃
    • State必须是两位大写字符


    这里使用正则表达式来验证,如下:
    • ^\d{5}([\-]\d{4})?$:验证5位或者9位的邮政编码
    • \b([A-Z]{2})\b :验证2位的state


    添加如下的代码段:

    ' Microsoft SQL Server Integration Services Script Component

    ' Write scripts using Microsoft Visual Basic 2008.

    ' ScriptMain is the entry point class of the script.

     

    Imports System

    Imports System.Data

    Imports System.Math

    Imports Microsoft.SqlServer.Dts.Pipeline.Wrapper

    Imports Microsoft.SqlServer.Dts.Runtime.Wrapper

    Imports System.Text.RegularExpressions

     

    <Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute()> _

    <CLSCompliant(False)> _

    Public Class ScriptMain

        Inherits UserComponent

     

        Private zipRegex As Regex = New Regex("@^\d{5}([\-]\d{4})?$", RegexOptions.None)

        Private stateRegex As Regex = New Regex("@\b([A-Z]{2})\b", RegexOptions.None)

        Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)

            'all fields except zip must have a value

            Dim isGood As Boolean = True

            If Row.FirstName_IsNull Or Row.LastName_IsNull Or Row.City_

            Then

                Row.GoodFlag = False

                Return

            End If

     

            If Not Row.Zip_IsNull Then

                Dim zip As String = Row.Zip.Trim()

                'zip must match regex if present

                If zipRegex.IsMatch(zip) Then

                    Row.CleanedZip = zip

                    isGood = True

                Else

                    'try to clean up the zip

     

                    If zip.Length > 5 Then

                        zip = zip.Substring(0, 5)

                        If zipRegex.IsMatch(zip) Then

                            Row.CleanedZip = zip

                            isGood = True

                        Else

                            isGood = False

                        End If

                    End If

                End If

            End If

     

            If isGood Then

     

                Dim state As String

                state = Row.State.Trim().ToUpper()

                If stateRegex.IsMatch(state) Then

                    Row.CleanedState = state

                Else

                    isGood = False

                End If

            End If

            Row.GoodFlag = isGood

     

        End Sub

    End Class

    这段代码执行验证规则,在方法Input0_ProcessInputRow内,首先检查字段是否为空,除了zip,这里使用了ColumnsName_IsNull属性,如果数据为空,它返回true。
    下一步,如果Zip列不为空,并且通过正则表达式验证,将它的值赋给CleanedZip,以便保存到目标表中。如果没有通过正则表达式验证,代码检查Zip长度是否大于5,如果是,截取前5位并使用正则表达式验证,如果通过验证,赋值给CleanedZip,isGood赋值为true,否则的话isGood赋值为false。
    去掉State的前空格和后空格,转换成大写,然后使用正则表达式来验证,如果通过验证将它的值赋值给CleanedState,否则isGood赋值为false。
     根据isGood的值将数据送到相应的表中,拖放一个Conditional Split task,将script task和它连接起来。双击Conditional Split的编辑界面,使用条件GoodFlag == TRUE 添加一个输出。这样数据将会被分成两部分。
    添加两个OLE DB Destination,一个指向Contacts表,一个指向ContactErrorQueue表。将Conditional Split和Contacts表连接起来。因为Conditional Split有多个输出,选择符合条件GoodFlag == TRUE的这一股,剩下的指向ContactsErrorQueue表。最后执行这个package如图4

    图4

    最后有14行数据进入到Contracts表中,4行数据进入到ContactsErrorQueue表中,如图5。

    图5

      

    调试脚本组件

    在脚本任务这个章节我们讲述了如何使用断点 调试,在脚本组件中我们不能使用这个特性,在代码中设置的断点会被忽略,你不许诉诸 于Row Count或者Data Riewer。
    Row Count的功能很明显,它显示有多少数据通过数据流,Data Viewer更加方便。点击Script Component和Conditional Split之间的连线 ,右击选择Data Viewers,在弹出的Data Flow Path Editor对话框中选择Data Viewer标签点击Add,选择Data Viewer Type为Grid,选择想要查看的列,最后点击保存。如图6

    图6

      

    再次运行这个package,将会看到Data Viewer界面,这里显示从Script Component中输出的数据,如图7。点击Play按钮程序继续运行,或关闭界面,程序也会继续运行下去。

    图7

      

    这里我们只能看到数据不能看到代码的执行情况。

      

    总结

    这一章中我们看到SSIS中的一些可以编写脚本的任务,使用表达式动态设置属性,使用表达式语言来完成数据转换的任务,如何使用脚本任务控制工作流,使用脚本组建清洗数据。通过一些练习我们可以更好地掌握如何使用脚本。

    作者:Tyler Ning
    出处:http://www.cnblogs.com/tylerdonet/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,如有问题,请微信联系冬天里的一把火

  • 相关阅读:
    centos7.6 使用yum安装mysql5.7
    解决hadoop本地库问题
    docker-compose 启动警告
    docker 安装zabbix5.0 界面乱码问题解决
    docker 部署zabbix问题
    zookeeper 超时问题
    hbase regionserver异常宕机
    (转载)hadoop 滚动升级
    hadoop Requested data length 86483783 is longer than maximum configured RPC length
    zkfc 异常退出问题,报错Received stat error from Zookeeper. code:CONNECTIONLOSS
  • 原文地址:https://www.cnblogs.com/tylerdonet/p/2182539.html
Copyright © 2011-2022 走看看