托管 UDT 使您能够扩展 SQL Server 的类型系统
当类型注册为数据库的可用类型之一后,就可以开始在创建对象(如表)时使用它,如下所示:www.iTbulo.comR9jWYOn
CREATE TABLE Points ( PointID int NOT NULL, Pnt Point NOT NULL )在表定义中使用 UDT 不需要特殊编码。使用与内部类型(如 int 或 nchar)一样的方式来定义表。www.iTbulo.comR9jWYOn
在我深入阐述之前,让我们看一下使用 Yukon 中用户定义类型的属性和方法的语法。它非常类似于 C# 和 Visual Basic .NET 的语法,只不过在这里属性或方法前面是两个冒号 (::) 而不是一个句点。到 Beta2 版时,:: 符号将要消失,而代之以句点符号。以下为属性和方法的语法:www.iTbulo.comR9jWYOn
Property Use Syntax: <implemented_type>::<property_name> = <scalar_expression> Method Use Syntax: <implemented_type>::<method_name>([arguments])要使用 T-SQL 为表填充数据,可以运行如下脚本:www.iTbulo.comR9jWYOn
DECLARE @startPoint Point DECLARE @endPoint Point SET @startPoint = CAST('10:10' AS Point) SET @endPoint::X = 5 SET @endPoint::Y = 3 INSERT Points VALUES(1, @startPoint) INSERT Points VALUES(2, @endPoint)对于任何使用过以前版本 SQL Server 的 T-SQL 变量、DML 语句以及 SELECT 语句的人来说,这些代码中许多都是很熟悉的。但是,还是有一些 T-SQL 代码的元素不太一样。第一个是使用 CAST 函数将 X 和 Y 的值赋给 @startPoint。当您以这种方式使用 CAST 函数时,将对 UDT 调用 Parse 方法以便为 UDT 实例填充数据。接下来,@endPoint 变量的 X 和 Y 属性被单独设置,从而使您能够显示地把值传递给 UDT 的属性。www.iTbulo.comR9jWYOn
代码的下一部分使用标准的 INSERT 语句把 UDT 类型的实例插入到 Points 表中。从存储在表中的 UDT 选择适当的值是通过语法 ColumnName::Property 或 ColumnName::Method 指定想调用的属性或方法的过程。即使方法不带参数,同样需要圆括号。在随后的示例中,您将从整个点集中选取 X 和 Y 的值:www.iTbulo.comR9jWYOn
SELECT Pnt::X AS XValue, Pnt::Y AS YValue FROM Points在这里我将选取一点并将它存储到变量 @pt 中,然后使用 DistanceTo 方法检查该点到表中另外一点的距离:www.iTbulo.comR9jWYOn
DECLARE @pt Point SELECT @pt = Pnt FROM Points WHERE PointID = 2 SELECT Pnt::DistanceTo(@pt) AS Distance FROM Points WHERE PointID = 1下一个例子,如图 6 所示,说明了如何在 Yukon 中使用 Address 类(假设其为 YukonCLR 程序集的一部分并且您已经创建了它的类型)。首先,创建类型 Address 的三个变量。其次,赋予地址信息并使用 cityStateZip 方法获取格式化的城市、州以及邮政编码。代码的第二部分利用 CAST 函数将第一个地址 (@addr) 复制到第二个地址 (@addr2) 中。这创建了一个副本,而不是对第一个变量的引用。随后对于 @addr 的任何改变将不会反映在 @addr2 中。最后,检查变量 @addr3 以确定它是否为空。由于该变量只是被声明而从未被赋值,它实际上为空,正如您看到的那样。www.iTbulo.comR9jWYOn
使用 DROP TYPE 语句可以很容易地删除 UDT,下例中将删除 Point UDT:www.iTbulo.comR9jWYOn
DROP TYPE Point不过这里面有点蹊跷 — 如果 UDT 当前正被使用(如,在一个列的定义中),就好像 Point 示例中那样,该怎么办呢? 很明显,如果其他对象依赖于该类型,您将不能从数据库中删除这一类型。因此必须在删除类型本身之前,确保删除掉了所有使用该类型的对象。这对于删除程序集同样适用。在删除程序集之前,必须先删除所有的 UDT。基于最后这个示例,将按照下面的方法来删除 YukonCLR 程序集:www.iTbulo.comR9jWYOn
DROP TABLE Points DROP TYPE POINT DROP TYPE Address DROP ASSEMBLY YukonCLR正如您所看见的,删除其中任意对象的语法是很简单的。当删除一个程序集时,便从当前的数据库中删除了基本代码,并且如果您想要将它添加回数据库中,必须拥有一个可用的编译版本。www.iTbulo.comR9jWYOn
由于受多种因素(例如,存储表示形式、排序和接口)的影响,ALTER TYPE 使用起来并不顺手。如果必须要更改,则一定要删除并重新创建这些对象。不过,ALTER ASSEMBLY 对于修补现有程序集代码中的错误很有效。www.iTbulo.comR9jWYOn
如果您对此有疑惑,这里提供对于在托管 ADO.NET 技术中和非托管客户端 API —(OLE DB、ODBC 以及 ADO)中 UDT 的深层支持。www.iTbulo.comR9jWYOn
现在,您了解了如何在 Yukon 和 .NET 中实现用户定义类型以及如何在 Yukon 中使用这些实现。当然,UDT 还有一些其他功能我没有在这里探究,这些内容可能会在以后的 MSDN Magazine 中详解。www.iTbulo.comR9jWYOn
相关文章请参见:www.iTbulo.comR9jWYOn
Creating User-Defined Data Typeswww.iTbulo.comR9jWYOn
Peter W. DeBetta 是 Wintellect 公司的教员,同时他还是帮助客户使用 Visual Basic、ASP、C#、ASP.NET 以及 SQL Server 开发企业级软件解决方案的顾问和开发人员。Peter 出版过一些合著书籍,他目前正致力于一本关于 SQL Server“Yukon”的书,该书将由 Microsoft Press 出版。www.iTbulo.comR9jWYOn![]()
文章评论
共有 0人发表了评论 查看完整内容