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

我们通过如程序代码列表11-20的 T-SQL 语法对该数据表进行添加、修改与查询数据的操作:

程序代码列表 11-20:通过 T-SQL 访问用户自定义数据类型

--各属性的大小写有别

--若当前的数据填错,不必等到 Insert 就会有错误出来

DECLARE @s Seat,@s2 Desk

SET @s=CONVERT(Seat,N'25,香蕉椅')

SET @s2=CONVERT(Desk,N'100,餐桌')

INSERT BikeSeats VALUES(@s,@s2)

SET @s=CONVERT(Seat,N'20,飞行椅')

SET @s2=CONVERT(Desk,N'30,小圆桌')

INSERT BikeSeats VALUES(@s,@s2)

GO

 

--若没有定义 Mutator 函数,

--直接 Update 一个用户自定义类型两个以上的属性时,

--无法以一句话来设

UPDATE BikeSeats SET deskInfo.Size=30 WHERE SeatID=2

UPDATE BikeSeats SET deskInfo.Type=N'小方桌' WHERE SeatID=2

GO

 

--可以通过 "字段.属性" 的方式取得自定义类型个别的属性

SELECT SeatID, SeatInfo.Size '尺寸',SeatInfo.Type '样式',

DeskInfo.Size '尺寸2',DeskInfo.Type '样式2' FROM BikeSeats

程序代码列表11- 20 中的 SELECT 查询结果如图11-25 所示:

图11-25  查询数据表中的自定义数据类型的内容

通过CONVERT 函数调用两个类各自实现的 ToString 函数:

SELECT CONVERT (nvarchar, SeatInfo), CONVERT (nvarchar, DeskInfo) FROM BikeSeats

WHERE SeatID=1

我们可以得到如图11-26 的结果:

图11-26  查询数据表中的自定义数据类型的内容

程序式码列表 11-20 中我通过一般的 Update 语法来更新自定义数据类型的内容,但若该类型有两个以上的属性时,就会需要两句独立的 Update 语法来分别设置不同的属性,这会让人觉得很笨 L。为此,你需要在类中定义 Mutator 函数,并通过 IsMutator 参数定义该函数可用来更新数据,程序代码范例如程序代码列表11-21:

程序代码列表 11-21  通过自定义的 Mutator 函数来更新自定义数据类型的内容

'Mutator 让 T-SQL 可以执行如下的语法

' Update tbl Set <UDT 字段>.<Mutator 函数()> WHERE...

<SqlMethod(ismutator:=True, onnullcall:=False)> _

Public Sub SetDesk(ByVal sSize As SqlTypes.SqlInt16, _

ByVal strType As SqlTypes.SqlString)

    '避免用户在 Update 时输入 NULL,所以通过 SqlTypes

    '来定义数据类型,并检查 NULL

    If sSize.IsNull Or strType.IsNull Then

        m_size = -1

        m_type = "类型不明"

        is_Null = True

    Else

        Me.Size = sSize.Value

        Me.Type = strType.Value

    End If

End Sub

当有 Mutator 函数后,就可以通过调用该函数,以一句 T-SQL 语法更新自定义类型的多个属性:

UPDATE BikeSeats SET DeskInfo.SetDesk(40,N'小方桌') WHERE SeatID=2

我们接着通过如程序代码11-22的T-SQL语法插入 NULL 数据,通过T-SQL 的 Convert 函数来检验类 (VB.NET 的 Sub New) ToString 与 Parse 等函数的功能是否正常。

程序代码列表11-22  针对用户自定义数据类型进一步测试其他的运算

--测试 NULL

--故意加入 NULL 数据

INSERT BikeSeats DEFAULT VALUES

GO

DECLARE @s Seat,@s2 Desk

INSERT BikeSeats VALUES(@s,@s2)

 

--查看覆写 ToString 函数时,是否有考虑到 NULL

SELECT CONVERT(nvarchar,SeatInfo),CONVERT(nvarchar,DeskInfo) FROM BikeSeats

测试结果如图11-27所示。

图11-27  查询数据表中的自定义数据类型的内容

另外,我们再编写一个用户自定义函数如程序代码列表11-23,以此调用程序代码列表11-17 所提供的 IComparable 接口所实现的 CompareTo函数,该函数放在上一节所介绍的用户自定义函数的类内,注册与使用皆是以用户自定义函数的方式:


 

程序代码列表11-23  以 .NET 编写用户自定义函数,以此比较自定义数据类型的大小

'传进用户自定义数据类型,通过数据类型类所实现的 CompareTo 函数比较大小

<System.Data.Sql.SqlFunction(Name:="CompareDesk", IsDeterministic:=True)> _

Public Shared Function CompareDesk (ByVal obj1 As Desk, ByVal obj2 As Desk, _

ByVal intCompare As Integer) As Integer

    Select Case intCompare

        Case 0 '依照预定 Desk 自己的 CompareTo 比较

            Return obj1.CompareTo(obj2)

        Case 1 '依照 Size 比

            Return obj1.Size.CompareTo(obj2.Size)

        Case 2 '依照 Type 比

            Return obj1.ToString.CompareTo(obj2.Type)

    End Select

End Function

在上述范例中我们提供用户输入两个 Desk 类型的变量,并通过第三个参数决定比较的方式。而第一种比较方式就是调用程序代码列表11-17 的 CompareTo 方法。第二与第三种选择则是分别以各变量数据类自身提供的 CompareTo 方法做比较,也就是数值或字符串数据的比较。

接着,我们通过 T-SQL 来比较一下存入数据表内的用户自定义数据类实例的大小,程序代码范例如程序代码列表11-24:

程序代码列表11-24  比较自定义数据类实例的大小

CREATE FUNCTION CompareDesk(@obj1 Desk,@obj2 Desk,@intCompare INT)

RETURNS INT

EXTERNAL NAME YukonCLR.[YukonCLR.UserDefineFunc].CompareDesk

 

--数据类型比较

--通过 SqlUserDefinedType 属性设置参数 IsByteOrdered:=True

--以序列化过后的二进制字节内容来比较大小

DECLARE @s desk,@s2 desk,@res INT

SELECT @s=deskInfo FROM BikeSeats WHERE SeatID=1

SELECT @s2=deskInfo FROM BikeSeats WHERE SeatID=2

PRINT N'依照 Serialize 后的 Bynary 比:'

IF @s>@s2

PRINT CONVERT(nvarchar,@s) + ' > ' + CONVERT(nvarchar,@s2)

ELSE

BEGIN

IF @s=@s2

     PRINT CONVERT(nvarchar,@s) + ' = ' + CONVERT(nvarchar,@s2)

ELSE

     PRINT CONVERT(nvarchar,@s) + ' < ' + CONVERT(nvarchar,@s2)

END

 

--调用自定义的 Comparedesk 函数比较大小

PRINT ''

PRINT N'调用我们在类内编写的 CompareTo 函数,也就是依照 ToString 的字符串大小比:'

SELECT @res=dbo.Comparedesk(@s,@s2,0)

IF @res>0

PRINT CONVERT(nvarchar,@s) + ' > ' + CONVERT(nvarchar,@s2)

ELSE

BEGIN

IF @res=0

     PRINT CONVERT(nvarchar,@s) + ' = ' + CONVERT(nvarchar,@s2)

ELSE

     PRINT CONVERT(nvarchar,@s) + ' < ' + CONVERT(nvarchar,@s2)

END

PRINT ''

 

PRINT N'依照 type 的字符串大小比:'

SELECT @res=dbo.Comparedesk(@s,@s2,2)

IF @res>0

PRINT CONVERT(nvarchar,@s) + ' > ' + CONVERT(nvarchar,@s2)

ELSE

BEGIN

IF @res=0

     PRINT CONVERT(nvarchar,@s) + ' = ' + CONVERT(nvarchar,@s2)

ELSE

     PRINT CONVERT(nvarchar,@s) + ' < ' + CONVERT(nvarchar,@s2)

END

程序代码列表 11-24 的执行结果如下:

依照 Serialize 后的 Bynary 比:

100,餐桌 > 30,小方桌

 

调用我们在类内编写的 CompareTo 函数,也就是依照 ToString 的字符串大小比:

100,餐桌 < 30,小方桌

 

依照 type 的字符串大小比:

100,餐桌 > 30,小方桌

另外,若 SqlUserDefinedType 属性设置成 IsByteOrderd,则以用户自定义类型所定义的数据字段内的实例可以直接比较大小(比较大小时依照 binary 的内容比大小)。因此也能够在该字段上设置索引,我们以下列的 T-SQL 语法在用户自定义数据类型所定义的字段上创建索引并测试。

CREATE INDEX idxSeat ON BikeSeats(DeskInfo)

SELECT SeatID, DeskInfo.Size '尺寸',DeskInfo.Type '样式2' FROM BikeSeats

ORDER BY DeskInfo

最后,我们通过以下的 T-SQL 语法直接调用自定义数据类型类内所定义的方法:

SELECT DeskInfo.GetPrice() 餐桌价格 FROM BikeSeats

执行结果如下:

餐桌价格

-----------

200

300

若要部署该用户自定义数据类型到 SQL Server 2005,除了可以通过 Visual Studio 2005 提供的部署功能外,你还可以使用如程序代码列表11-25所示的T-SQL语法:

程序代码列表11-25  通过 T-SQL 定义通过 .NET 编写的用户自定义数据类型

CREATE ASSEMBLY YukonCLR FROM

'C:\BookSamples\SQL 2005 Dev\Ch11_Clr\YukonCLR\bin\YukonCLR.dll'

WITH PERMISSION_SET = UNSAFE

GO

 

CREATE TYPE Seat

EXTERNAL NAME YukonCLR.[YukonCLR.Seat]

GO

CREATE TYPE Desk

EXTERNAL NAME YukonCLR.[YukonCLR.Desk]

最后,若要移除数据库内先前建立的用户自定义数据类型,记得要先移除数据表,因为该数据表参照了用户自定义数据类型。然后才可以移自定义数据类型,之后才是组件。下列为移除的顺序。

DROP TABLE BikeSeats

DROP TYPE Seat

DROP TYPE Desk

DROP ASSEMBLY YukonClr

由于用户自定义数据类型提供了强大的数据定义功能,或许可以让你用它来实际操作局部的面向对象数据库。但相对来说,若用得不好,一定会造成数据处理上的不稳定,甚至性能不佳,因此在设计时不可不慎。

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

责任编辑:cyth

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