使用用户定义类型
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 函数或存储过程的参数。
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 继承的三个方法(GetParameterInfo、MapParameterNames 和 SetParameterInfo)之外,ISSCommandWithParameters 还提供 GetParameterProperties 和 SetParameterProperties 方法,这些方法用于处理服务器特定的数据类型。
注意 |
---|
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 的 ToString 或 ToXMLString 方法或通过 CAST/CONVERT 函数,在 SQL 语句中将 UDT 列显式映射到另一种类型,则在结果集中该列的类型将反映该列转换为的实际类型。
SQLColAttribute、SQLDescribeParam、SQLGetDescField
添加了四个新的驱动程序特定的描述符字段,用于为结果集的 UDT 列或存储过程/参数化查询的 UDT 参数提供附加信息,以便通过 SQLColAttribute、SQLDescribeParam 和 SQLGetDescField 等函数检索。
这四个新添加的描述符字段分别为 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
此外,向 SQLColumns 和 SQLProcedureColumns 函数返回的结果集添加了三个新的驱动程序特定列,以提供有关 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 数据类型转换时,二进制数据将转换为十六进制字符串。
请参阅
参考
ISSCommandWithParameters (OLE DB)