11.3创建SQLServer2005服务器段物件
来源:优易学  2010-1-12 12:05:31   【优易学:中国教育考试门户网】   资料下载   IT书店

 

11.3.4.1  UDT的模板

微软向来为开发软件提供了友善的开发环境,若你不想徒手创建程序代码,可以直接使用 Visual Studio 2005 的SQL Server 项目类型中的模板(Template)来开发。在项目名称上点选右键新建项目,打开如图11-21 的窗口,选择 User-Defined Type,点选“添加”按钮后 Visual Studio 2005 将会帮你创建如程序代码列表 11-10 的模板,而你只需要在模板中的各函数内填入商业逻辑即可。

图11-21  在 Visual Studio 2005 项目中新建UDT的模板

模板内容如下:

程序代码列表11-10  Visual Studio 2005 为用户自定义数据类型提供的开发模板

Imports System

Imports System.Data

Imports System.Data.SqlClient

Imports System.Data.SqlTypes

Imports Microsoft.SqlServer.Server

 

<Serializable()> _

<Microsoft.SqlServer.Server.SqlUserDefinedType(Format.Native)> _

Public Structure UserDefineType

    Implements INullable

 

    Public Overrides Function ToString() As String

        ' Put your code here

        Return ""

    End Function

 

    Public ReadOnly Property IsNull() As Boolean Implements INullable.IsNull

        Get


            ' Put your code here

            Return m_Null

        End Get

    End Property

 

    Public Shared ReadOnly Property Null As UserDefineType

        Get

            Dim h As UserDefineType = New UserDefineType

            h.m_Null = True

            Return h

        End Get

    End Property

 

    Public Shared Function Parse(ByVal s As SqlString) As UserDefineType

        If s.IsNull Then

            Return Null

        End If

 

        Dim u As UserDefineType = New UserDefineType

        ' Put your code here

        Return u

    End Function

 

    ' This is a place-holder method

    Public Function Method1() As String

        ' Put your code here

        Return "Hello"

    End Function

 

    ' This is a place-holder static method

    Public Shared Function Method2() As SqlString

        ' Put your code here

        Return New SqlString("Hello")

    End Function

 

    ' This is a place-holder field member

    Public m_var1 As Integer

    ' Private member

    Private m_Null As Boolean

End Structure

由上面的模板程序架构我们可以发现实现 UDT 的时候,SQL Server 2005 规定必须先完成下列步骤:

1.   创建 Public 类(Class)或结构(Structure)。

2.   在类中定义 Serializable 与 SqlUserDefinedTypeAttribute 特性(Attribute)。

3.   处理数据字段的NULL值
为了处理数据字段的 NULL 值,因此UDT 必须要实现 INullable 接口,若某条记录的字段值需要是 NULL,例如添加记录,而该自定义数据类型字段存放的是 NULL 时,才有得对应。该界面只有一个返回布尔类型的 IsNull 属性,以此告知该实例所代表的内容是否为 NULL。
除了实现 INullable 接口外,还必须编写一个 Public 属性名称为 NULL、返回内容为 NULL 的实例。实现这个属性对用户自定义数据类型来说是必要的,让前端程序在访问字段内容为 NULL 的记录时,SQL Server 能够通过它取得意义为 NULL 的对象实例。若你没有实际操作它,在编译与注册组件时不会出错(这时还不知道这个程序集要做什么J),但在注册用户自定义数据类型时会出错。

4.   提供 String 的转换:实现静态 Parse 方法与覆写(Overrides)继承自 Object 的 ToString 方法,也就是提供字符串与 UDT 类型的转换。Parse 提供从字符串转换为对象,而 ToString 提供从对象转换为字符串的方式。

5.         提供 Public 属性去访问类中所定义的 Private数据。

上述第二点中,SqlUserDefinedTypeAttribute 属性的 Format 枚举参数告知要如何将对象实例序列化后放置到数据表的字段内,它的枚举类型有三:

Format.Native序列化对象实例时最为有效率,但缺乏弹性。只可以用在该类型所有需要存储(persist)属性的数据类型都是固定长度,例如数值、日期等数据类型,也就是单纯值类型(value-type)的变量才可以使用,而对象或字符串类型就不可以,因为它是参照类型的变量。

Format.UserDefined此定义兼具弹性与效率,但用户需要自定义序列化的方式,也就是类型或结构需要实现 IBinarySerialize接口,该界面有Write 和 Read 两个方法。而这个属性还需要搭配 MaxByteSize 属性的设置。

Unknown序列化的格式未知。

SqlUserDefinedTypeAttribute 属性上还有一些其他选择性参数设置,分别描述如下:

IsByteOrdered存放序列化后的对象个体的字节是否可作为排序顺序。Format 参数需要设置成 Native 或 UserDefined,IsByteOrdered 才可以设为 True。设为 True 后,该数据类型以序列化后的字节来对比大小,也就依此排序与创建索引,默认值为 False。

IsFixedLength自定义数据类型的各实例序列化后,存放在数据表字段内是否为固定长度,默认为 false。

MaxByteSize自定义数据类型的实例最大的字节数,当 Format 参数设置为 Native 时,不可以设置这个参数,但若 Format 设置的是 UserDefined,则一定要设置这个参数。

接下来,我们用两个 VB.NET 所实现的 UDT 类当作范例来解释,Seat 类使用的 Format 参数为 Native ,而 Desk 类使用的 Format 参数是 UserDefined,后续将提供一些高级的讨论。

11.3.4.2  用户自定义数据类型的基本范例

首先是简单地赋予模板程序逻辑内容的 Seat 类,其声明与 INullable “接口”的实现如程序代码列表11-11:

程序代码列表 11-11  声明用户自定义类型的类,并实际操作 INullable 接口

'User Defined Type 一定需要能够 Searialize 才能整个地放到数据表字段中

'若不指定名字,会自动以 Class 名当做 Type 名称

<Serializable(), SqlUserDefinedType(Format.Native), _

Runtime.InteropServices.StructLayout(LayoutKind.Sequential)> _

Public Class Seat

    Implements INullable

    Private is_Null As Boolean = True

    '由于序列化设置的是 Native,所以只能以 SQL 默认的数据类型组合

    Private m_size As Short

    Private m_type As Short

 

 

    Public Sub New()

        '初始化创建自定义数据类型的对象实例时,设置

        '代表 Null 的各属性意义,避免用户直接访问内

        '涵为 Null 的实例之属性

        m_size = -1

        m_type = -1

        is_Null = True

    End Sub

 

    '实现 INullable “接口”唯一的 IsNull 属性

    Public ReadOnly Property IsNull() As Boolean _

    Implements System.Data.SqlTypes.INullable.IsNull

        Get

            Return is_Null

        End Get

    End Property

由于在程序代码列表11-11的范例中定义序列化的方式为 Format.Native,因此需要存储的 Private 类型变量 is_NULL、m_size、m_type 我们都定义成固定长度的数据类型,如 Boolean 或 Short。变量不可以声明成String 类型,因为它是不固定长度。

而通过 IsNull 属性返回 SQL Server 告知该实例是否为 NULL ,程序逻辑很简单,就是返回 is_NULL 类型变量当时的设置值。

接下来是设置 Seat 类中返回给数据字段或变量是 NULL 值的静态 Public 属性,实现的方式也很简单,内容如程序代码列表11-12:

程序代码列表11-12  实际操作NULL属性,返回我们所设置的内容代表NULL的对象实例

'通过 NULL 返回包含值定义为 NULL 的对象个体

Public Shared ReadOnly Property NULL() As Seat

    Get

        Dim sea As New Seat

        sea.is_NULL = True

        Return (sea)

    End Get

End Property

在 NULL 属性中,我们返回一个新的 Seat 实例,并设置该实例代表 NULL 的方式,当 SQL Server 需要返回存入数据表的记录,在用户自定义数据类型的字段值是 NULL 时,便通过这个属性函数创建实例。

除了可以存储与显示 NULL 外,UDT 也必须提供实例与字符串间转换的能力。因此必须实现静态Parse 方法,在传入单一 SqlString 类型代表对象实例的文本参数后,与 NULL 属性一样返回对象的实例,但该对象实例的内涵与该字符串的意义相同。也就是提供字符串与 UDT 类型的转换。程序代码范例如程序代码列表11-13:

程序代码列表11-13  实际操作 Parse 函数,将字符串转成自定义数据类型的实例

Public Shared Function Parse(ByVal s As SqlString) As Seat

    '传进来的数据应该是 N'10,赛车椅' 的格式,与 ToString 呼应

    Dim sea As New Seat

    If s.IsNull Then

        Return Nothing

    Else

        Try

            Dim strAry() As String = s.ToString.Split(",")

            sea.Size = Short.Parse(strAry(0))

            sea.Type = strAry(1)

        Catch

            '若用户输入的数据类型不对,或是无法设置到相关的属性

            '默认给定的值

            sea.Size = -1

            sea.Type = "类型不明"

        End Try

    End If

    Return sea

End Function

因为在 Seat 类中,我们定义了两个属性:Size 和 Type,因此在程序代码列表 11-13 中,要求输入的字符串一定要通过逗号分隔两种属性的值,在建立了对象实例后,分别赋予各属性再返回该实例。

反过来,当用户要将实例转成文本类型时,我们要通过覆写(Override) .NET Framework 规范的 Object 对象之 ToString 方法,让 UDT 提供从实例转换成字符串的方式。程序代码范例如列表11-14:

程序代码列表11-14  覆写Object的ToString 函数,将自定义数据类型的实例转成字符串

'需要提供 ToString,Parse 以及 Null 让 UDT 正常运行

'通过覆写 ToString,让显示数据时可以通过 T-SQL Convert 该 Type

'成字符串类型

Public Overrides Function ToString() As String

    If Me.IsNull Then

        Return "NULL"

    Else

        Return Me.Size.ToString() & "," & Me.Type

    End If

End Function

范例中,我们仅是简单地将两项属性组成字符串后返回,并呼应程序代码列表 11-13 所实现的 Parse 函数,两项属性间以逗号隔开。

上述的程序对象在部署之后可以通过以下的 T-SQL 语法测试字符串与对象实例的转换:

SELECT CONVERT(Seat,N'0,赛车椅').Type

我们将 “0,赛车椅” 字符串通过 CONVERT 函数转型成 Seat 对象类实例,SQL Server 就是调用我们先前实现的 Parse 属性。并通过该类的实例取回自定义数据类型的 Type 属性,所得到的结果如图11-22 所示:

图11-22  测试Convert 的功能所得到的结果

另外,类中用来访问与设置Type 和Size属性的Get 和Set 函数定义如程序代码列表11-15:

程序代码列表11-15  自定义的Seat数据类型提供Size和Type两个属性

Public Property Size() As Short

    Get

        Return Me.m_size

    End Get

    Set(ByVal Value As Short)

        m_size = Value

        Me.is_Null = False

    End Set

End Property

 

Public Property Type() As String

    '强制用户输入的 Type 只能是赛车椅,飞行椅或香蕉椅

    Get

    Select Case Me.m_type

            Case -1

                Return "类型不明"

            Case 0

                Return "赛车椅"

            Case 1

                Return "飞行椅"

            Case 2

                Return "香蕉椅"

            Case Else

                Return "类型不明"

        End Select

    End Get

    Set(ByVal Value As String)

        Select Case Value

            Case "类型不明"

                m_type = -1

            Case "赛车椅"

                m_type = 0

            Case "飞行椅"

                m_type = 1

            Case "香蕉椅"

                m_type = 2

            Case Else

                Throw New ArgumentException( _

                "Type 类型必须填入赛车椅,飞行椅,香蕉椅三者之一")

        End Select

        If m_type >= 0 Then Me.is_Null = False

    End Set

End Property

 

上一页  [1] [2] [3] [4] [5] [6] 下一页

责任编辑:cyth

文章搜索:
 相关文章
热点资讯
热门课程培训