大型 CLR 用户定义类型 (OLE DB)
本主题讨论 SQL Server Native Client 中为支持大型公共语言运行时 (CLR) 用户定义类型 (UDT) 而对 OLE DB 进行的更改。
有关 SQL Server Native Client 中对大型 CLR UDT 的支持的详细信息,请参阅大型 CLR 用户定义类型。
数据格式
SQL Server Native Client 使用 ~0 表示其大小对于大型对象 (LOB) 类型不受限制的值的长度。~0 还表示大于 8,000 个字节的 CLR UDT 的大小。
下表显示了参数和行集中的数据类型映射:
SQL Server 数据类型 |
OLE DB 数据类型 |
内存布局 |
值 |
---|---|---|---|
CLR UDT |
DBTYPE_UDT |
BYTE[](字节数组) |
132 (oledb.h) |
UDT 值表示为字节数组。支持与十六进制字符串之间的转换。文字值表示为带有“0x”前缀的十六进制字符串。十六进制字符串是以 16 为基数的二进制数据的文本表示形式。一个例子便是从服务器类型 varbinary(10) 到 DBTYPE_STR 的转换,这会产生一个 20 个字符的十六进制表示形式,其中每对字符都表示一个字节。
ITableDefinition::CreateTable 中的数据类型映射
在需要 UDT 列时,ITableDefinition::CreateTable 使用的 DBCOLUMNDESC 结构将使用以下信息:
OLE DB 数据类型 (wType) |
pwszTypeName |
SQL Server 数据类型 |
rgPropertySets |
---|---|---|---|
DBTYPE_UDT |
忽略 |
UDT |
必须包括 DBPROPSET_SQLSERVERCOLUMN 属性集。 |
ICommandWithParameters::GetParameterInfo
通过 prgParamInfo 在 DBPARAMINFO 结构中返回的信息如下所示:
参数类型 |
wType |
ulParamSize |
bPrecision |
bScale |
dwFlags DBPARAMFLAGS_ISLONG |
---|---|---|---|---|---|
DBTYPE_UDT (长度小于或等于 8,000 个字节) |
"DBTYPE_UDT" |
n |
未定义 |
未定义 |
清除 |
DBTYPE_UDT (长度大于 8000 个字节) |
"DBTYPE_UDT" |
~0 |
未定义 |
未定义 |
设置 |
ICommandWithParameters::SetParameterInfo
在 DBPARAMBINDINFO 结构中提供的信息必须符合以下规定:
参数类型 |
pwszDataSourceType |
ulParamSize |
bPrecision |
bScale |
dwFlags DBPARAMFLAGS_ISLONG |
---|---|---|---|---|---|
DBTYPE_UDT (长度小于或等于 8,000 个字节) |
DBTYPE_UDT |
n |
忽略 |
忽略 |
如果将使用 DBTYPE_IUNKNOWN 传递参数,则必须进行设置。 |
DBTYPE_UDT (长度大于 8000 个字节) |
DBTYPE_UDT |
~0 |
忽略 |
忽略 |
忽略 |
ISSCommandWithParameters
应用程序使用 ISSCommandWithParameters 获取和设置在“参数属性”一节中定义的参数属性。
IColumnsRowset::GetColumnsRowset
返回的列如下所示:
列类型 |
DBCOLUMN_TYPE |
DBCOLUMN_COLUMNSIZE |
DBCOLUMN_PRECISION |
DBCOLUMN_SCALE |
DBCOLUMN_FLAGS_ISLONG |
DBCOLUMNS_ISSEARCHABLE |
DBCOLUMN_OCTETLENGTH |
---|---|---|---|---|---|---|---|
DBTYPE_UDT (长度小于或等于 8,000 个字节) |
DBTYPE_UDT |
n |
NULL |
NULL |
清除 |
DB_ALL_EXCEPT_LIKE |
n |
DBTYPE_UDT (长度大于 8000 个字节) |
DBTYPE_UDT |
~0 |
NULL |
NULL |
设置 |
DB_ALL_EXCEPT_LIKE |
0 |
对于 UDT,还会定义以下列:
列标识符 |
类型 |
说明 |
---|---|---|
DBCOLUMN_UDT_CATALOGNAME |
DBTYPE_WSTR |
对于 UDT 列,为在其中定义了 UDT 的目录的名称。 |
DBCOLUMN_UDT_SCHEMANAME |
DBTYPE_WSTR |
对于 UDT 列,为在其中定义了 UDT 的架构的名称。 |
DBCOLUMN_UDT_NAME |
DBTYPE_WSTR |
对于 UDT 列,为仅由一个部分组成的 UDT 名称。 |
DBCOLUMN_ASSEMBLY_TYPENAME |
DBTYPE_WSTR |
对于 UDT 列,为 UDT 的完整类型名称。通过程序集类型的完全限定名称,可以使用 Type.GetType 方法实例化该类型的对象。 |
IColumnsInfo::GetColumnInfo
在 DBCOLUMNINFO 结构中返回的信息如下所示:
参数类型 |
wType |
ulColumnSize |
bPrecision |
bScale |
dwFlags DBCOLUMNFLAGS_ISLONG |
---|---|---|---|---|---|
DBTYPE_UDT (长度小于或等于 8,000 个字节) |
DBTYPE_UDT |
n |
~0 |
~0 |
清除 |
DBTYPE_UDT (长度大于 8000 个字节) |
DBTYPE_UDT |
~0 |
~0 |
~0 |
设置 |
COLUMNS 行集(架构行集)
对于 UDT 类型,返回以下列值:
列类型 |
DATA_TYPE |
COLUMN_FLAGS, DBCOLUMFLAGS_ISLONG |
CHARACTER_OCTET_LENGTH |
---|---|---|---|
DBTYPE_UDT (长度小于或等于 8,000 个字节) |
DBTYPE_UDT |
清除 |
n |
DBTYPE_UDT (长度大于 8000 个字节) |
DBTYPE_UDT |
设置 |
0 |
对于 UDT,还会定义以下列:
列标识符 |
类型 |
说明 |
---|---|---|
SS_UDT_CATALOGNAME |
DBTYPE_WSTR |
对于 UDT 列,为在其中定义了 UDT 的目录的名称。 |
SS_UDT_SCHEMANAME |
DBTYPE_WSTR |
对于 UDT 列,为在其中定义了 UDT 的架构的名称。 |
SS_UDT_NAME |
DBTYPE_WSTR |
对于 UDT 列,为仅由一个部分组成的 UDT 名称。 |
SS_ASSEMBLY_TYPENAME |
DBTYPE_WSTR |
对于 UDT 列,为 UDT 的完整类型名称。通过程序集类型的完全限定名称,可以使用 Type.GetType 方法实例化该类型的对象。 |
对于 PROCEDURE_PARAMETERS 行集,DATA_TYPE 包含与 COLUMNS 架构行集相同的值,并且 TYPE_NAME 包含 UDT。对于该行集,也会定义相同的附加列。
用户定义类型不会出现在 PROVIDER_TYPES 架构行集中。
绑定和转换
绑定数据类型 |
UDT 到服务器 |
非 UDT 到服务器 |
UDT 来自服务器 |
非 UDT 来自服务器 |
---|---|---|---|---|
DBTYPE_UDT |
支持 (5) |
错误 (1) |
支持 (5) |
错误 (4) |
DBTYPE_BYTES |
支持 (5) |
不适用 |
支持 (5) |
不适用 |
DBTYPE_WSTR |
支持 (2)、(5) |
不适用 |
支持 (3)、(5)、(6) |
不适用 |
DBTYPE_BSTR |
支持 (2)、(5) |
不适用 |
支持 (3)、(5) |
不适用 |
DBTYPE_STR |
支持 (2)、(5) |
不适用 |
支持 (3)、(5) |
不适用 |
DBTYPE_IUNKNOWN |
支持 (6) |
不适用 |
支持 (6) |
不适用 |
DBTYPE_VARIANT (VT_UI1 | VT_ARRAY) |
支持 (5) |
不适用 |
支持 (3)、(5) |
不适用 |
DBTYPE_VARIANT (VT_BSTR) |
支持 (2)、(5) |
不适用 |
不适用 |
不适用 |
符号含义
符号 |
含义 |
---|---|
1 |
如果使用 ICommandWithParameters::SetParameterInfo 指定了 DBTYPE_UDT 之外的服务器类型,而取值函数类型为 DBTYPE_UDT,则执行该语句时将出错。将出现 DB_E_ERRORSOCCURRED 错误,参数状态将为 DBSTATUS_E_BADACCESSOR。 如为类型不是 UDT 的服务器参数指定 UDT 类型的参数,则会出现错误。 |
2 |
数据从十六进制字符串转换为二进制数据。 |
3 |
数据从二进制数据转换为十六进制字符串。 |
4 |
在使用 CreateAccessor 或 GetNextRows 时,会发生验证。错误为 DB_E_ERRORSOCCURRED 错误。绑定状态设置为 DBBINDSTATUS_UNSUPPORTEDCONVERSION。 |
5 |
可能会使用 BY_REF。 |
6 |
UDT 参数可以绑定为 DBBINDING 中的 DBTYPE_IUNKNOWN。如果绑定到 DBTYPE_IUNKNOWN,则表明应用程序想要使用 ISequentialStream 接口将数据作为流进行处理。如果使用者在绑定中将 wType 指定为 DBTYPE_IUNKNOWN 类型,并且对应的列或存储过程的输出参数为 UDT,SQL Server Native Client 将返回 ISequentialStream。对于输入参数,SQL Server Native Client 将查询 ISequentialStream 接口。 如果是大型 UDT,可以选择不绑定 UDT 数据的长度,而是使用 DBTYPE_IUNKNOWN 绑定。但是,对于小型 UDT,必须绑定长度。如果满足以下一个或多个条件,可以将 DBTYPE_UDT 参数指定为大型 UDT:
对于行数据,仅允许对大型 UDT 进行 DBTYPE_IUNKNOWN 绑定。通过对 Rowset 或 Command 对象的 IColumnsInfo 接口使用 IColumnsInfo::GetColumnInfo 方法,可以确定列是否为大型 UDT 类型。如果满足以下一个或多个条件,DBTYPE_UDT 列即为大型 UDT 列:
|
可以绑定 DBTYPE_NULL 和 DBTYPE_EMPTY 用于输入参数,但不能用于输出参数或结果。当绑定用于输入参数时,对于 DBTYPE_NULL,状态必须设置为 DBSTATUS_S_ISNULL,对于 DBTYPE_EMPTY 则必须设置为 DBSTATUS_S_DEFAULT。DBTYPE_BYREF 不能与 DBTYPE_NULL 或 DBTYPE_EMPTY 一起使用。
DBTYPE_UDT 还可以转换为 DBTYPE_EMPTY 和 DBTYPE_NULL。但是,DBTYPE_NULL 和 DBTYPE_EMPTY 无法转换为 DBTYPE_UDT。这与 DBTYPE_BYTES 是一致的。ISSCommandWithParameters 用于将 UDT 处理为参数。
OLE DB 核心服务 (IDataConvert) 提供的数据转换不适用于 DBTYPE_UDT。
不支持其他绑定。
IRowsetFind 的可比性
对于 UDT 类型,仅支持进行以下比较:
EQ
NE
IGNORE
如果试图进行其他任何比较,将返回 DB_E_BADCOMPAREOP 错误。
对 UDT 的 BCP 支持
UDT 值只能够作为字符值或二进制值导入和导出。
UDT 的下级客户端行为
对于下级客户端,UDT 会进行类型映射,如下所示:
客户端版本 |
DBTYPE_UDT (长度小于或等于 8,000 个字节) |
DBTYPE_UDT (长度大于 8000 个字节) |
---|---|---|
SQL Server 2000 及更早版本 |
varbinary |
image |
SQL Server 2005 |
UDT |
varbinary(max) |
SQL Server 2008 和更高版本 |
UDT |
UDT |
如果 DataTypeCompatibility (SSPROP_INIT_DATATYPECOMPATIBILITY) 设置为“80”,大型 UDT 类型对客户端所显示的类型将与它们对下级客户端所显示的相同。