使用用户定义类型

SQL Server 2005 介绍了用户定义类型 (UDT)。UDT 允许您将对象和自定义数据结构存储在 SQL Server 数据库中,从而扩展了 SQL 类型系统。UDT 可以包含多种数据类型并且可具有行为,这使它们不同于由单一 SQL Server 系统数据类型构成的传统别名数据类型。使用生成可验证代码的 .NET 公共语言运行时 (CLR) 所支持的任何语言都可以定义 UDT,这些语言包括 Microsoft Visual C#® 和 Visual Basic® .NET。数据公开为 .NET 类或结构的字段和属性,行为则由类或结构的方法来定义。

UDT 可用作表的列定义、Transact-SQL 批处理中的变量,或者 Transact-SQL 函数或存储过程的参数。有关 UDT 的详细信息,请参阅 使用 CLR 用户定义类型

SQL Server Native Client OLE DB 访问接口

SQL Server Native Client OLE DB 访问接口支持 UDT 作为带有元数据信息的二进制类型,这允许您将 UDT 作为对象管理。UDT 列公开为 DBTYPE_UDT,并且这些列的元数据通过核心 OLE DB 接口 IColumnRowset 和新增的 ISSCommandWithParameters 接口公开。

注意注意

IRowsetFind::FindNextRow 方法不适用于 UDT 数据类型。如果将 UDT 用作搜索列类型,则返回 DB_E_BADCOMPAREOP。

数据绑定和强制

下表说明将所列数据类型与某一 SQL Server UDT 一同使用时出现的绑定和强制。UDT 列通过 SQL Server Native Client OLE DB 访问接口公开为 DBTYPE_UDT.可以通过适当的架构行集获取元数据,这样即可将您自行定义的类型作为对象来管理。

数据类型

到服务器

UDT

到服务器

非 UDT

从服务器

UDT

从服务器

非 UDT

DBTYPE_UDT

支持6

错误1

支持6

错误5

DBTYPE_BYTES

支持6

不适用2

支持6

不适用2

DBTYPE_WSTR

支持3,6

不适用2

支持4,6

不适用2

DBTYPE_BSTR

支持3,6

不适用2

支持4

不适用2

DBTYPE_STR

支持3,6

不适用2

支持4,6

不适用2

DBTYPE_IUNKNOWN

不支持

不适用2

不支持

不适用2

DBTYPE_VARIANT (VT_UI1 | VT_ARRAY)

支持6

不适用2

支持4

不适用2

DBTYPE_VARIANT (VT_BSTR)

支持3,6

不适用2

不适用

不适用2

1如果使用 ICommandWithParameters::SetParameterInfo 指定了 DBTYPE_UDT 之外的服务器类型,而取值函数类型为 DBTYPE_UDT,执行该语句时将出错(DB_E_ERRORSOCCURRED;参数状态为 DBSTATUS_E_BADACCESSOR)。如果不是这样,数据将发送到服务器,但服务器会返回错误,指示不存在从 UDT 到参数的数据类型的隐式转换。

2超出本主题的范围。

3从十六进制字符串转换为二进制数据。

4从二进制数据转换为十六进制字符串。

5可能在创建取值函数时或在提取时执行验证,错误为 DB_E_ERRORSOCCURRED,绑定状态设置为 DBBINDSTATUS_UNSUPPORTEDCONVERSION。

6可以使用 BY_REF。

可以绑定 DBTYPE_NULL 和 DBTYPE_EMPTY 用于输入参数,但不能用于输出参数或结果。为输入参数进行绑定时,状态必须设置为 DBSTATUS_S_ISNULL 或 DBSTATUS_S_DEFAULT。

还可以将 DBTYPE_UDT 转换为 DBTYPE_EMPTY 和 DBTYPE_NULL,但无法将 DBTYPE_NULL 和 DBTYPE_EMPTY 转换为 DBTYPE_UDT。这与 DBTYPE_BYTES 的情况是一致的。

注意注意

使用新接口 ISSCommandWithParameters(继承自 ICommandWithParameters)可以将 UDT 作为参数处理。应用程序必须使用此接口为 UDT 参数至少设置 DBPROPSET_SQLSERVERPARAMETER 属性集的 SSPROP_PARAM_UDT_NAME。如果不这样做,ICommand::Execute 将返回 DB_E_ERRORSOCCURRED。此接口和属性集将在本主题的下文中介绍。

如果将某一用户定义类型插入某列,而该列的大小不足以包含该类型的所有数据,ICommand::Execute 将返回 S_OK,且状态为 DB_E_ERRORSOCCURRED。

OLE DB 核心服务 (IDataConvert) 提供的数据转换不适用于 DBTYPE_UDT。不支持其他绑定。

OLE DB 行集的添加和更改内容

SQL Server Native Client 在许多核心 OLE DB 架构行集中添加了新值或进行了更改。

PROCEDURE_PARAMETERS 架构行集

在 PROCEDURE_PARAMETERS 架构行集中添加了以下内容。

列名

类型

说明

SS_UDT_CATALOGNAME

DBTYPE_WSTR

由三部分组成的名称标识符。

SS_UDT_SCHEMANAME

DBTYPE_WSTR

由三部分组成的名称标识符。

SS_UDT_NAME

DBTYPE_WSTR

由三部分组成的名称标识符。

SS_UDT_ASSEMBLY_TYPENAME

DBTYPE_WSTR

程序集限定名,其中包括 CLR 引用所需的类型名称和所有程序集标识。

SQL_ASSEMBLIES 架构行集

SQL Server Native Client OLE DB 访问接口公开用于说明注册的 UDT 的特定于访问接口的新架构行集。可以将 ASSEMBLY 服务器指定为 DBTYPE_WSTR,但它在行集中不存在。如果未指定,行集将默认使用当前服务器。下表中定义了 SQL_ASSEMBLIES 架构行集。

列名

类型

说明

ASSEMBLY_CATALOG

DBTYPE_WSTR

包含该类型的程序集的目录名称。

ASSEMBLY_SCHEMA

DBTYPE_WSTR

包含该类型的程序集的架构名称或所有者名称。尽管程序集的作用域为数据库而不是架构,但它们仍具有在此所反映的所有者。

ASSEMBLY_NAME

DBTYPE_WSTR

包含该类型的程序集的名称。

ASSEMBLY_ID

DBTYPE_UI4

包含该类型的程序集的对象 ID。

PERMISSION_SET

DBTYPE_WSTR

指示程序集的访问范围的值。这些值包括“SAFE”、“EXTERNAL_ACCESS”和“UNSAFE”。

ASSEMBLY_BINARY

DBTYPE_BYTES

程序集的二进制表示形式。

SQL_ASSEMBLIES_ DEPENDENCIES 架构行集

SQL Server Native Client OLE DB 访问接口公开特定于访问接口的新架构行集,该行集说明指定服务器的程序集依赖项。ASSEMBLY_SERVER 可由调用方指定为 DBTYPE_WSTR,但在该行集中不存在。如果未指定,行集将默认使用当前服务器。SQL_ASSEMBLY_DEPENDENCIES 架构行集在下表中定义。

列名

类型

说明

ASSEMBLY_CATALOG

DBTYPE_WSTR

包含该类型的程序集的目录名称。

ASSEMBLY_SCHEMA

DBTYPE_WSTR

包含该类型的程序集的架构名称或所有者名称。尽管程序集的作用域为数据库而不是架构,但它们仍具有在此所反映的所有者。

ASSEMBLY_ID

DBTYPE_UI4

程序集的对象 ID。

REFERENCED_ASSEMBLY_ID

DBTYPE_UI4

所引用的程序集的对象 ID。

SQL_USER_TYPES 架构行集

SQL Server Native Client OLE DB 访问接口公开新的架构行集 SQL_USER_TYPES,该行集说明何时添加指定服务器的已注册 UDT。UDT_SERVER 必须由调用方指定为 DBTYPE_WSTR,但它在该行集中不存在。在下表中定义 SQL_USER_TYPES 架构行集。

列名

类型

说明

UDT_CATALOGNAME

DBTYPE_WSTR

对于 UDT 列,此属性是一个字符串,它指定定义 UDT 的目录的名称。

UDT_SCHEMANAME

DBTYPE_WSTR

对于 UDT 列,此属性是一个字符串,它指定定义 UDT 的架构的名称。

UDT_NAME

DBTYPE_WSTR

包含 UDT 类的程序集的名称。

UDT_ASSEMBLY_TYPENAME

DBTYPE_WSTR

完整类型名称 (AQN) 包括带有命名空间前缀(如果适用)的类型名称。

COLUMNS 架构行集

COLUMNS 架构行集添加了以下列。

列名

类型

说明

SS_UDT_CATALOGNAME

DBTYPE_WSTR

对于 UDT 列,此属性是一个字符串,它指定定义 UDT 的目录的名称。

SS_UDT_SCHEMANAME

DBTYPE_WSTR

对于 UDT 列,此属性是一个字符串,它指定定义 UDT 的架构的名称。

SS_UDT_NAME

DBTYPE_WSTR

UDT 的名称

SS_UDT_ASSEMBLY_TYPENAME

DBTYPE_WSTR

完整类型名称 (AQN) 包括带有命名空间前缀(如果适用)的类型名称。

OLE DB 属性集的添加和更改内容

SQL Server Native Client 在许多核心 OLE DB 属性集中添加了新值或进行了更改。

DBPROPSET_SQLSERVERPARAMETER 属性集

为通过 OLE DB 支持 UDT,SQL Server Native Client 实现了新的 DBPROPSET_SQLSERVERPARAMETER 属性集,该属性集包含以下值。

名称

类型

说明

SSPROP_PARAM_UDT_CATALOGNAME

DBTYPE_WSTR

由三部分组成的名称标识符。

对于 UDT 参数,此属性是一个字符串,它指定定义用户定义类型的目录的名称。

SSPROP_PARAM_UDT_SCHEMANAME

DBTYPE_WSTR

由三部分组成的名称标识符。

对于 UDT 参数,此属性是一个字符串,它指定定义用户定义类型的架构的名称。

SSPROP_PARAM_UDT_NAME

DBTYPE_WSTR

由三部分组成的名称标识符。

对于 UDT 列,此属性是一个字符串,它指定仅由一个部分组成的用户定义类型名称。

SSPROP_PARAM_UDT_NAME 是必需的。SSPROP_PARAM_UDT_CATALOGNAME 和 SSPROP_PARAM_UDT_SCHEMANAME 是可选的。如果任何属性指定有误,将返回 DB_E_ERRORSINCOMMAND。如果未指定 SSPROP_PARAM_UDT_CATALOGNAME 和 SSPROP_PARAM_UDT_SCHEMANAME,则必须在定义表的同一数据库和架构中定义 UDT。如果 UDT 定义没有位于表所在的架构中(但位于相同的数据库中),则必须指定 SSPROP_PARAM_UDT_SCHEMANAME。如果 UDT 定义位于不同的数据库中,则必须指定 SSPROP_PARAM_UDT_CATALOGNAME 和 SSPROP_PARAM_UDT_SCHEMANAME。

DBPROPSET_SQLSERVERCOLUMN 属性集

为支持在 ITableDefinition 接口中创建表,SQL Server Native Client 向 DBPROPSET_SQLSERVERCOLUMN 属性集添加了以下三个新列。

名称

说明

类型

说明

SSPROP_COL_UDT_CATALOGNAME

UDT_CATALOGNAME

VT_BSTR

对于 DBTYPE_UDT 类型的列,此属性是一个字符串,它指定定义 UDT 的目录的名称。

SSPROP_COL_UDT_SCHEMANAME

UDT_SCHEMANAME

VT_BSTR

对于 DBTYPE_UDT 类型的列,此属性是一个字符串,它指定定义 UDT 的架构的名称。

SSPROP_COL_UDT_NAME

UDT_NAME

VT_BSTR

对于 DBTYPE_UDT 类型的列,此属性是一个字符串,它指定仅由一个部分组成的 UDT 名称。对于其他列类型,此属性返回空字符串。

注意注意

UDT 不出现在 PROVIDER_TYPES 架构行集中。所有列都具有读写访问权限。

ADO 将通过使用“说明”列中的相应条目引用这些属性。

SSPROP_COL_UDTNAME 是必需的。SSPROP_COL_UDT_CATALOGNAME 和 SSPROP_COL_UDT_SCHEMANAME 是可选的。如果任何属性指定有误,将返回 DB_E_ERRORSINCOMMAND。

如果既未指定 SSPROP_COL_UDT_CATALOGNAME 也未指定 SSPROP_COL_UDT_SCHEMANAME,则必须在定义表的同一数据库和架构中定义 UDT。

如果 UDT 定义没有与表位于同一架构中(但位于同一数据库中),则必须指定 SSPROP_COL_UDT_SCHEMANAME。

如果 UDT 定义位于不同的数据库中,则必须指定 SSPROP_COL_UDT_CATALOGNAME 和 SSPROP_COL_UDT_SCHEMANAME。

OLE DB 接口的添加和更改内容

SQL Server Native Client 在许多核心 OLE DB 接口中添加了新值或进行了更改。

ISSCommandWithParameters 接口

为通过 OLE DB 支持 UDT,SQL Server Native Client 实现了若干更改,包括添加 ISSCommandWithParameters 接口。这一新接口继承自核心 OLE DB 接口 ICommandWithParameters。除了从 ICommandWithParameters 继承的三个方法(GetParameterInfoMapParameterNamesSetParameterInfo)之外,ISSCommandWithParameters 还提供 GetParameterPropertiesSetParameterProperties 方法,这些方法用于处理服务器特定的数据类型。

注意注意

ISSCommandWithParameters 接口也利用新的 SSPARAMPROPS 结构。

IColumnsRowset 接口

ISSCommandWithParameters 接口之外,SQL Server Native Client 还向调用 IColumnsRowset::GetColumnRowset 方法所返回的行集添加了以下新值。

列名

类型

说明

DBCOLUMN_SS_UDT_CATALOGNAME

DBTYPE_WSTR

UDT 目录名称标识符。

DBCOLUMN_SS_UDT_SCHEMANAME

DBTYPE_WSTR

UDT 架构名称标识符。

DBCOLUMN_SS_UDT_NAME

DBTYPE_WSTR

UDT 名称标识符。

DBCOLUMN_SS_ASSEMBLY_TYPENAME

DBTYPE_WSTR

程序集限定名,其中包括 CLR 引用所需的类型名称和所有程序集标识。

通过查看上面指定的添加的 UDT 元数据,可以在 DBCOLUMN_TYPE 设置为 DBTYPE_UDT 时将服务器 UDT 列与其他二进制类型区分开。如果该数据不完整,服务器类型为 UDT。对于非 UDT 服务器类型,这些列的返回结果始终为 NULL。

SQL Server Native Client ODBC 驱动程序

在 SQL Server Native Client ODBC 驱动程序中进行了一些更改以支持 UDT。SQL Server Native Client ODBC 驱动程序将 SQL Server UDT 映射到 SQL_SS_UDT 驱动器特定的 SQL 数据类型标识符。UDT 列呈现为 SQL_SS_UDT。如果通过使用 UDT 的 ToStringToXMLString 方法或通过 CAST/CONVERT 函数,在 SQL 语句中将 UDT 列显式映射到另一种类型,则在结果集中该列的类型将反映该列转换为的实际类型。

SQLColAttribute、SQLDescribeParam、SQLGetDescField

添加了四个新的驱动程序特定的描述符字段,用于为结果集的 UDT 列或存储过程/参数化查询的 UDT 参数提供附加信息,以便通过 SQLColAttributeSQLDescribeParamSQLGetDescField 等函数检索。

这四个新添加的描述符字段分别为 SQL_CA_SS_UDT_CATALOG_NAME、SQL_CA_SS_UDT_SCHEMA_NAME、SQL_CA_SS_UDT_TYPE_NAME 和 SQL_CA_SS_UDT_ASSEMBLY_TYPE_NAME。

SQLColumns、SQLProcedureColumns

此外,向 SQLColumnsSQLProcedureColumns 函数返回的结果集添加了三个新的驱动程序特定列,以提供有关 UDT 结果集列或 UDT 参数的附加信息。这三个新列分别为 SS_UDT_CATALOG_NAME、SS_UDT_SCHEMA_NAME 和 SS_UDT_ASSEMBLY_TYPE_NAME。

支持的转换

从 SQL 转换为 C 数据类型时,SQL_C_WCHAR、SQL_C_BINARY 和 SQL_C_CHAR 可全部转换为 SQL_SS_UDT。不过请注意,从 SQL_C_WCHAR 和 SQL_C_CHAR SQL 数据类型转换时,二进制数据将转换为十六进制字符串。

从 C 转换为 SQL 数据类型时,SQL_C_WCHAR、SQL_C_BINARY 和 SQL_C_CHAR 可全部转换为 SQL_SS_UDT。不过请注意,从 SQL_C_WCHAR 和 SQL_C_CHAR SQL 数据类型转换时,二进制数据将转换为十六进制字符串。