如何:通过使用公共语言运行时集成创建和运行 SQL Server 用户定义的类型
通过将**“用户定义的类型”**添加到 SQL Server 公共语言运行时 (SQL CLR) 数据库项目,从而创建 SQL 用户定义的类型。 部署成功后,可以将该类型用在可使用系统类型的所有上下文中。 这包括列定义、变量、参数、函数结果、游标、触发器和复制。 用户定义的类型为用户提供了 SQL Server 数据类型系统的扩展功能以及定义复杂结构类型的能力。
提示
对于在以下说明中使用的某些 Visual Studio 用户界面元素,您的计算机可能会显示不同的名称或位置。这些元素取决于您所使用的 Visual Studio 版本和您所使用的设置。有关更多信息,请参见 Visual Studio 设置。
创建用户定义的类型
创建 SQL 用户定义的类型
打开一个现有的**“SQL CLR 数据库项目”**,或者创建一个新项目。 有关更多信息,请参见如何:为使用 SQL Server 公共语言运行时集成的数据库对象创建项目。
在**“项目”菜单上选择“添加新项”**。
在**“添加新项”对话框中,选择“用户定义的类型”**。
键入用户定义的新类型的**“名称”**。
添加用于定义和创建用户定义的类型的代码。 请参见此过程后面的第一个示例。
在**“解决方案资源管理器”中打开“TestScripts”**文件夹,并双击 Test.sql 文件。
提示
您可以将其他脚本指定为默认调试脚本。 有关更多信息,请参见如何:编辑 Test.sql 脚本以运行使用 SQL Server 公共语言运行时集成的对象。
将代码添加到**“Test.sql”(Visual C++ 中为“debug.sql”**)文件中以执行用户定义的类型。 请参见此过程后面的第二个示例。
按 F5 生成、部署并调试该用户定义的类型。 有关如何不进行调试而直接部署的信息,请参见如何:将 SQL CLR 数据库项目项部署到 SQL Server。
重要事项 SQL Server 2005 和 SQL Server 2008 只支持使用 .NET Framework 2.0、3.0 或 3.5 版生成的 SQL Server 项目。 如果您尝试部署SQL Server项目,SQL Server 2005或SQL Server 2008,将显示错误消息: Deploy error (SQL01268): .NET SqlClient Data Provider: Msg 6218, Level 16, State 3, Line 1 CREATE ASSEMBLY for assembly 'AssemblyName' failed because assembly 'AssemblyName' failed verification. Check if the referenced assemblies are up-to-date and trusted (for external_access or unsafe) to execute in the database(在进行校验是您要部署的程序集的名称)。 有关更多信息,请参见如何:为使用 SQL Server 公共语言运行时集成的数据库对象创建项目。
查看所示的结果“输出”窗口和选择显示输出: 数据库输出。
示例
此示例创建一个 Point 类型,该类型的用法与其他简单类型一样。 使用 Serializable 和 SqlUserDefinedTypeAttribute 特性来修饰这个类声明。 SqlUserDefinedTypeAttribute 的 Format 属性决定了用户定义的类型的存储格式。 该类型通过实现 Parse 和 ToString 方法来实现字符串转换。 此外,该类型还实现两个属性过程,以便为此类所表示的点获取和设置 X 和 Y 的值。
Imports System
Imports System.Data.SqlTypes
Imports Microsoft.SqlServer.Server
<Serializable()>
<SqlUserDefinedType(Format.Native)>
Public Structure Point
Implements INullable
Private m_x As Int32
Private m_y As Int32
Private is_Null As Boolean
Public Property X() As Int32
Get
Return (Me.m_x)
End Get
Set(ByVal Value As Int32)
m_x = Value
End Set
End Property
Public Property Y() As Int32
Get
Return (Me.m_y)
End Get
Set(ByVal Value As Int32)
m_y = Value
End Set
End Property
Public ReadOnly Property IsNull() As Boolean Implements INullable.IsNull
Get
Return is_Null
End Get
End Property
Public Shared ReadOnly Property Null() As Point
Get
Dim pt As Point = New Point
pt.is_Null = True
Return pt
End Get
End Property
Public Overrides Function ToString() As String
If Me.IsNull() Then
Return Nothing
Else
Return Me.m_x & ":" & Me.m_y
End If
End Function
Public Shared Function Parse(ByVal s As SqlString) As Point
If s = SqlString.Null Then
Return Null
End If
If s.ToString() = SqlString.Null.ToString() Then
Return Null
End If
If s.IsNull Then
Return Null
End If
'Parse input string here to separate out coordinates
Dim str As String = Convert.ToString(s)
Dim xy() As String = str.Split(":"c)
Dim pt As New Point()
pt.X = CType(xy(0), Int32)
pt.Y = CType(xy(1), Int32)
Return (pt)
End Function
Public Function Quadrant() As SqlString
If m_x = 0 And m_y = 0 Then
Return "centered"
End If
Dim stringResult As String = ""
Select Case m_x
Case 0
stringResult = "center"
Case Is > 0
stringResult = "right"
Case Is < 0
stringResult = "left"
End Select
Select Case m_y
Case 0
stringResult = stringResult & " center"
Case Is > 0
stringResult = stringResult & " top"
Case Is < 0
stringResult = stringResult & " bottom"
End Select
Return stringResult
End Function
End Structure
using System;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
[Serializable()]
[SqlUserDefinedType(Format.Native)]
public struct Point : INullable
{
private Int32 m_x;
private Int32 m_y;
private bool is_Null;
public Int32 X
{
get
{
return (this.m_x);
}
set
{
m_x = value;
}
}
public Int32 Y
{
get
{
return (this.m_y);
}
set
{
m_y = value;
}
}
public bool IsNull
{
get
{
return is_Null;
}
}
public static Point Null
{
get
{
Point pt = new Point();
pt.is_Null = true;
return (pt);
}
}
public override string ToString()
{
if (this.IsNull)
{
return "NULL";
}
else
{
return this.m_x + ":" + this.m_y;
}
}
public static Point Parse(SqlString s)
{
if (s.IsNull)
{
return Null;
}
// Parse input string here to separate out coordinates
string str = Convert.ToString(s);
string[] xy = str.Split(':');
Point pt = new Point();
pt.X = Convert.ToInt32(xy[0]);
pt.Y = Convert.ToInt32(xy[1]);
return (pt);
}
public SqlString Quadrant()
{
if (m_x == 0 && m_y == 0)
{
return "centered";
}
SqlString stringReturn = "";
if (m_x == 0)
{
stringReturn = "center";
}
else if (m_x > 0)
{
stringReturn = "right";
}
else if (m_x < 0)
{
stringReturn = "left";
}
if (m_y == 0)
{
stringReturn = stringReturn + " center";
}
else if (m_y > 0)
{
stringReturn = stringReturn + " top";
}
else if (m_y < 0)
{
stringReturn = stringReturn + " bottom";
}
return stringReturn;
}
}
将用于执行和测试用户定义类型 (Point) 的代码添加到 Test.sql 文件中,该文件位于项目的**“TestScripts”**文件夹中。 例如,若要检查新类型,可以创建一个使用此类型的表。 下面的示例演示如何在创建表的过程中使用 Point 类型。
CREATE TABLE test_table (column1 Point)
go
INSERT INTO test_table (column1) VALUES ('1:2')
INSERT INTO test_table (column1) VALUES ('-2:3')
INSERT INTO test_table (column1) VALUES ('-3:-4')
select column1.Quadrant() from test_table
请参见
任务
如何:为使用 SQL Server 公共语言运行时集成的数据库对象创建项目
如何:通过使用公共语言运行时集成创建和运行 SQL Server 存储过程
如何:通过使用公共语言运行时集成创建和运行 SQL Server 触发器
如何:通过使用公共语言运行时集成创建和运行 SQL Server 聚合
如何:通过使用公共语言运行时集成创建和运行 SQL Server 用户定义的函数