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

在 Type 的属性设置中,因为记录 Type 设置的 m_Type 私有变量是数值类型,但显示结果与用户设置数据时,需要的是文本类型。因此在取得 Type 属性值的 Get 函数中,我们利用 Select Case 语法将 m_type 的值转成文本返回。同理在设置属性的 Set 函数中,对应设置的文本转成不同的数值放入到 m_type 变量中。

你可以通过如下的 T-SQL 语法测试设置的 Type 类型是否合乎规范,是否我们所建立的实例会存放在对应的设置中,也就是“类型不明”:

--使用错误的数据类型进行测试

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

SELECT CONVERT(Seat,'').Type

SELECT CONVERT(Seat,NULL).Type

上述分别测试出输入的 Type 不符要求,以及先前编写的类处理空字符串与 NULL 转换成 Seat 类型实例的逻辑,其结果都约略如图11-23所示:

图11-23  测试数据错误的结果

接下来我们测试把对象存入到含有上述自定义类型的数据表中,首先通过 T-SQL 创建测试用的数据表BikeSeats,语法如下:

CREATE TABLE BikeSeats

(

 SeatID INT IDENTITY NOT NULL,

 SeatInfo Seat ,

)

利用 T-SQL 添加一条数据到 BikeSeats 数据库中:

DECLARE @s Seat

SET @s.Size=25

SET @s.Type=N'香蕉椅'  --可以把此栏故意设错,观察 Exception

INSERT BikeSeats VALUES(@s)

在上述范例中声明 Seat 类型的变量,赋予各项属性后再插入到数据表中。接着用下列语法将记录从 BikeSeats 数据表中调出来,并将 Seat 对象实例转型成文字:

SELECT CONVERT(NVARCHAR,SeatInfo) FROM BikeSeats

你将会得到如图11-24 的结果,这也验证了先前 ToString 函数的程序逻辑:

图11-24  新建与查询数据表内含有自定义数据类型字段的结果

介绍完编写UDT类基本的要求后,我们再在类中增加一些功能。以下用 Desk 类做进一步的说明J

11.3.4.3  用户自定义数据类型较高级的范例

程序代码列表11-16另外创建 Desk 类,由于 SqlUserDefinedType 属性的 Format 参数使用的是 UserDefined,因此需要设置数据类型实例最大的字节数 MaxByteSize,由于等会要对数据字段进行排序,所以IsByteOrdered 必须设置 True,在后文中也会利用此项设置来比较对象实例的大小。

接下来,我们针对 Desk 类再进一步地提供自定义序列化的能力,并为该类加上自定义函数 GetPrice。

程序代码列表11-16  实现 IComparable 接口的 Write 和 Read 函数

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

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

MaxByteSize:=4000, IsByteOrdered:=True), _

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

Public Class Desk

    Implements INullable, IBinarySerialize, IComparable

    Private is_Null As Boolean = True

    Private m_size As Short

    '因为是自定义 Serialize 所以可以序列化文本类型的成员

    Private m_type As String

 

    Public Sub New()

        m_size = -1

        m_type = "类型不明"

        is_Null = True

    End Sub

 

    Public Sub Write(ByVal w As System.IO.BinaryWriter) _

    Implements IBinarySerialize.Write

        Dim bNull As Byte

        If is_Null Then

            bNull = 0

            w.Write(bNull)

        Else

            bNull = 1

            w.Write(bNull)

            w.Write(m_size)

            w.Write(m_type)

        End If

    End Sub

    Public Sub Read(ByVal r As System.IO.BinaryReader) _

    Implements IBinarySerialize.Read

        Dim bNull As Byte = r.ReadByte()

        If bNull = 0 Then

            is_Null = True

        Else

            is_Null = False

            m_size = r.ReadInt16

            m_type = r.ReadString()

        End If

    End Sub

由于我们自定义序列化实例的方式,所以在实现写入到媒介(如硬盘,网络等)的 Write 方法时,要将各属性依次写入,并要将该实例是否为 NULL 的条件一并写入。而实现 Read 方法读出先前存储的状态,做反序列化的操作。也就是提供相同顺序读取不同数据类型的数据,并赋予到当前的实例变量中。

我们还替 Desk 类实现了 IComparable 接口,该界面只有一个函数定义,就是 CompareTo 函数。该函数要求对象实例自身在与传入的对象实例比大小时,我们所实现的商业逻辑必须要返回大于零的值代表当前的实例比较大,若两个实例相等则返回零,若参数传入的实例比较大,则返回负值。程序代码范例如列表11-17:

程序代码列表11-17  实现 IComparable 接口的 CompareTo 函数

Public Function CompareTo(ByVal obj As Object) As Integer _

Implements IComparable.CompareTo

    '我们以两个对象的字符串结果来比较大小

    '如果当前的 Instance 是和 Nothing 对象来比,当然比较大

    If obj Is Nothing Then Return 1

   

    Dim desk As Desk = CType(obj, Desk)

    If (Me.IsNull) Then

        If desk.IsNull Then Return 0

        Return -1

    Else

        If desk.IsNull Then Return 1

        Return Me.ToString.CompareTo(desk.ToString())

    End If

End Function

在上述的范例中,仅以该对象的字符串表示来比较大小。另外,我们将编写一个用户自定义函数来调用 CompareTo方法如程序代码列表11-18所示。

我们最后在 Desk 类中加上一个自定义的方法,以此测试通过自定义数据类型是否也可以调用该类的方法,在下文中会通过 T-SQL 来调用这个方法:


 

程序代码列表11-18  为自定义数据类型新建函数

Public Function GetPrice() As Integer

    Dim intMoney As Integer

    Select Case m_type

        Case类型不明"

            intMoney = -1

        Case "小圆桌"

            intMoney = 100

        Case "餐桌"

            intMoney = 200

        Case "小方桌"

            intMoney = 300

    End Select

    Return intMoney

End Functio程序

由于 Type 属性现在是用字符串类型的 m_type变量在记录设置值,因此,不需要通过 Select Case 语法做转换对应字符串与数值的操作,程序代码较为简单,如列表11-19所示:

程序代码列表11-19  Desk类型的Size和ype属性

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

        Return m_type

    End Get

    Set(ByVal Value As String)

        If Value <> "小圆桌" And Value <> "餐桌" And Value <> "小方桌" And Value <> "类型不明" Then

            Throw New ArgumentException("Type 类型必须填入小圆桌,餐桌,小方桌三者之一")

        Else

            m_type = Value

            Me.is_Null = False

        End If

    End Set

End Property

另外,ToString 和 Parse 函数与前述的 Seat 类差异不大,在此也就不再详列。整个类编译并部署完毕后,通过 T-SQL 语法创建包含该类的数据表字段定义如下:

--将先前测试的 BikeSeats 数据库删除,重建一个自定义类型的数据表

DROP TABLE BikeSeats

CREATE TABLE BikeSeats

(

SeatID INT IDENTITY NOT NULL,

--利用用户自定义数据类型定义字段

SeatInfo Seat ,

DeskInfo Desk

)

 

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

责任编辑:cyth

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