创建用户定义类型 - 需求
适用于:SQL Server
在创建要在 Microsoft SQL Server中安装的 UDT) (用户定义的类型时,必须做出几个重要的设计决策。 对于大多数 UDT,建议将 UDT 作为结构创建,尽管也可以选择将其作为类创建。 UDT 定义必须符合创建 UDT 的规范,才能将其注册到 SQL Server。
实现 UDT 的要求
若要在 SQL Server 中运行,UDT 必须在 UDT 定义中实现以下要求:
UDT 必须指定 Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute。 System.SerializableAttribute 的使用是可选的,但建议使用。
UDT 必须通过在 Microsoft Visual Basic) Null 方法中创建公共静态 (共享,在 类或结构中实现 System.Data.SqlTypes.INullable 接口。 默认情况下,SQL Server为 null 感知。 这是为使在 UDT 中执行的代码能够识别 Null 值所必需的。
UDT 必须包含一个公共 静态 (或 Shared) Parse 方法(支持从 中进行分析)和一个用于转换为对象的字符串表示形式的公共 ToString 方法。
具有用户定义的序列化格式的 UDT 必须实现 System.Data.IBinarySerialize 接口并提供 Read 和 Write 方法。
UDT 必须实现 System.Xml。Serialization.IXmlSerializable 或所有公共字段和属性的类型都必须是 XML 可序列化或用 XmlIgnore 属性修饰的类型(如果需要重写标准序列化)。
一个 UDT 对象必须只存在一个序列化。 如果序列化或反序列化例程识别了某一特定对象的多个表示形式,则验证将失败。
SqlUserDefinedTypeAttribute.IsByteOrdered 必须 为 true 才能按字节顺序比较数据。 如果未实现 IComparable 接口,并且 SqlUserDefinedTypeAttribute.IsByteOrdered 为 false,则字节顺序比较将失败。
在类中定义的 UDT 必须具有不采用任何参数的公共构造函数。 您可以选择创建其他重载类构造函数。
该 UDT 必须将数据元素作为公共字段或属性过程公开。
公共名称不能超过 128 个字符,并且必须符合数据库标识符中定义的标识符SQL Server命名规则。
sql_variant 列不能包含 UDT 的实例。
无法从 Transact-SQL 访问继承的成员,因为SQL Server类型系统不知道 UDT 之间的继承层次结构。 但是,您可以在创建类的结构时使用继承,并且可以在该类型的托管代码实现方式中调用此类方法。
成员不能被重载,但类构造函数除外。 如果确实创建了重载方法,则注册程序集或在 SQL Server 中创建类型时不会引发错误。 在运行时将检测到重载的方法,而不是在创建类型时检测到。 只要永不调用重载的方法,重载的方法就可以存在于类中。 一旦您调用重载的方法,就会引发错误。
任何 静态 (或 共享) 成员都必须声明为常量或只读。 静态成员将无法改变。
如果 SqlUserDefinedTypeAttribute.MaxByteSize 字段设置为 -1,则序列化的 UDT 可以与当前 2 GB) (LOB) 大小限制 (大对象一样大。 UDT 的大小不能超过 MaxByteSized 字段中指定的值。
注意
尽管服务器不使用它来执行比较,但可以选择实现 System.IComparable 接口,该接口公开单个方法 CompareTo。 此方法用于客户端上希望精确比较或排序 UDT 值的情况中。
本机序列化
为您的 UDT 选择正确的序列化属性取决于您正尝试创建的 UDT 的类型。 本机序列化格式利用非常简单的结构,使SQL Server能够在磁盘上存储 UDT 的高效本机表示形式。 如果 UDT 简单且仅包含以下类型的字段,则建议使用 本机 格式:
bool、 byte、 sbyte、 short、 ushort、 int、 uint、 long、 ulong、 float、 double、 SqlByte、 SqlInt16、 SqlInt32、 SqlInt64、 SqlDateTime、 SqlSingle、 SqlDouble、 SqlMoney、 SqlBoolean
由上述类型的字段组成的值类型非常适合 本机 格式,例如 Visual C# 中的 结构 、 (或 Visual Basic) 中已知的 结构 。 例如,使用 本机 序列化格式指定的 UDT 可能包含另一个 UDT 的字段,该字段也是使用 本机 格式指定的。 如果 UDT 定义更为复杂,并且包含上述列表中的数据类型,则必须改为指定 用户定义的 序列化格式。
本机格式具有以下要求:
类型不得指定 Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute.MaxByteSize 的值。
所有字段必须均可序列化。
如果 UDT 是在类而不是结构中定义的,则必须将 System.Runtime.InteropServices.StructLayoutAttribute 指定为 StructLayout.LayoutKindSequential 。 此属性控制数据字段的物理布局,并用来按照成员的出现顺序对它们进行布局。 SQL Server使用此属性来确定具有多个值的 UDT 的字段顺序。
有关使用 本机 序列化定义的 UDT 的示例,请参阅 编码User-Defined类型中的点 UDT。
UserDefined 序列化
Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute 属性的 UserDefined 格式设置使开发人员可以完全控制二进制格式。 将 Format 属性属性指定为 UserDefined 时,必须在代码中执行以下操作:
指定可选的 IsByteOrdered 属性。 默认值是 false秒。
指定 Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute 的 MaxByteSize 属性。
编写代码,通过实现 System.Data.Sql.IBinarySerialize 接口来实现 UDT 的 Read 和 Write 方法。
有关使用 用户定义的 序列化定义的 UDT 的示例,请参阅 编码User-Defined类型中的货币 UDT。
注意
为了编制索引,UDT 字段必须使用本机序列化或者是持久化的。
序列化特性
属性确定如何使用序列化来构造 UDT 的存储表示形式以及如何按值将 UDT 传输到客户端。 创建 UDT 时,需要指定 Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute 。 Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute 属性指示类是 UDT,并指定 UDT 的存储。 可以选择指定 Serializable 属性,但SQL Server不需要此属性。
Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute 具有以下属性。
格式
指定序列化格式,可以是 本机 格式或 用户定义格式,具体取决于 UDT 的数据类型。
IsByteOrdered
一个布尔值,确定SQL Server如何对 UDT 执行二进制比较。
IsFixedLength
指示此 UDT 的所有实例是否都具有相同的长度。
MaxByteSize
实例的最大大小(以字节为单位)。 必须使用用户定义的序列化格式指定 MaxByteSize。 对于指定了用户定义序列化的 UDT, MaxByteSize 引用其序列化形式的 UDT 的总大小(由用户定义)。 MaxByteSize 的值必须在 1 到 8000 的范围内,或设置为 -1 以指示 UDT 大于 8000 字节 (总大小不能超过最大 LOB 大小) 。 考虑一个 UDT,其属性为 10 个字符的字符串 (System.Char) 。 当使用 BinaryWriter 序列化 UDT 时,序列化字符串的总大小为 22 字节:每个 Unicode UTF-16 字符占 2 个字节,乘以最大字符数,再加上因序列化二进制流而导致的系统开销 2 个控制字节。 因此,在确定 MaxByteSize 的值时,必须考虑序列化 UDT 的总大小:以二进制形式序列化的数据的大小以及序列化产生的开销。
ValidationMethodName
用于验证 UDT 的实例的方法的名称。
设置 IsByteOrdered
当 Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute.IsByteOrdered 属性设置为 true 时,实际上可以保证序列化的二进制数据可用于信息的语义排序。 因此,以字节排序的 UDT 对象的每个实例只能有一种序列化表示形式。 在序列化字节SQL Server中执行比较操作时,其结果应与托管代码中发生的相同比较操作相同。 当 IsByteOrdered 设置为 true 时,也支持以下功能:
可以对此类型的列创建索引。
可以对此类型的列创建主键和外键以及 CHECK 和 UNIQUE 约束。
能够使用 Transact-SQL ORDER BY、GROUP BY 和 PARTITION BY 子句。 此时,将使用该类型的二进制表示形式确定顺序。
在 Transact-SQL 语句中使用比较运算符的功能。
可以保持此类型的计算列。
请注意,当 IsByteOrdered 设置为 true 时,Native 和 UserDefined 序列化格式都支持以下比较运算符:
等于 (=)
不等于 (!=)
大于号 (>)
小于号 (<)
大于或等于 (>=)
小于或等于 (<=)
实现为 Null 性
除了正确指定程序集的属性外,类还必须支持为 Null 性。 加载到SQL Server中的 UDT 是 null 感知的,但为了使 UDT 识别 null 值,类必须实现 INullable 接口。 有关详细信息以及如何在 UDT 中实现可为空性的示例,请参阅 编码User-Defined类型。
字符串转换
若要支持与 UDT 的字符串转换,必须在类中提供 Parse 方法和 ToString 方法。 Parse 方法允许将字符串转换为 UDT。 它必须在 Visual Basic) 中声明为 静态 (或 共享 ,并采用 类型为 System.Data.SqlTypes.SqlString 的参数。 有关详细信息以及如何实现 Parse 和 ToString 方法的示例,请参阅 编码User-Defined类型。
XML 序列化
UDT 必须通过符合 XML 序列化协定来支持与 xml 数据类型的转换。 System.Xml。序列化命名空间包含用于将对象序列化为 XML 格式的文档或流的类。 可以选择使用 IXmlSerializable 接口实现 xml 序列化,该接口为 XML 序列化和反序列化提供自定义格式。
除了执行从 UDT 到 xml 的显式转换外,XML 序列化还使你能够:
在转换为 xml 数据类型后,对 UDT 实例的值使用 Xquery。
在参数化查询中使用 UDT,在 Web 方法中使用本机 XML Web 服务SQL Server。
使用 UDT 可以接收 XML 数据的大容量加载。
序列化包含具有 UDT 列的表的数据集。
UDT 在 FOR XML 查询中不序列化。 若要执行显示 UDT XML 序列化的 FOR XML 查询,请在 SELECT 语句中将每个 UDT 列显式转换为 xml 数据类型。 还可以将列显式转换为 varbinary、 varchar 或 nvarchar。
另请参阅
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈