sql_variant 数据类型的运行过程与 Microsoft® Visual Basic® 中的 variant 数据类型相似。它允许单一的列、参数或变量存储不同数据类型的数据值。例如,一个单一的 sql_variant 列能保存 int、decimal、char、binary 和 nchar 值。sql_variant 列的每个实例记录数据值和元数据信息,其中包括基本数据类型、最大大小、小数位数、精度和排序规则。
sql_variant 数据类型遵循以下规则:
在这个例子中,VariantCol 的值被设为无关联数据类型,即使空值来自一个 int 变量。
DECLARE @IntVar int
SET @IntVar = NULL
UPDATE SomeTable SET VariantCol = @IntVar WHERE PriKey = 123
sql_variant 列可以包含具有几种基本数据类型和排序规则的值,所以当比较 sql_variant 操作数时,要应用一些特殊规则。这些规则适用于各种比较操作,例如:
对于 sql_variant 比较,SQL Server 数据类型层次结构顺序被分组为数据类型系列( sql_variant 系列有最高的系列优先顺序)。
| 数据类型层次结构 | 数据类型系列 |
| sql_variant | sql_variant |
| datetime | Datetime |
| smalldatetime | Datetime |
| float | 近似数 |
| real | 近似数 |
| decimal | 精确数 |
| money | 精确数 |
| smallmoney | 精确数 |
| bigint | 精确数 |
| int | 精确数 |
| smallint | 精确数 |
| tinyint | 精确数 |
| bit | 精确数 |
| nvarchar | Unicode |
| nchar | Unicode |
| varchar | Unicode |
| char | Unicode |
| varbinary | Binary |
| binary | Binary |
| uniqueidentifier | Uniqueidentifier |
适用于 sql_variant 比较的规则如下:
在 sql_variant 值之间用这些规则进行比较,与用同样的规则在具有相同的基本数据类型的值之间进行比较相比,会产生不同的结果。
操作数 A |
操作数 B |
Non-variant 比较结果 |
sql_variant 比较结果 |
| '123' char | 111t | A > B | B > A |
| 50000 int | 5E1 float | A > B | B > A |
因为不同数据类型系列的值在比较谓词中引用前必须显式转换,只有当排序 sql_variant 列上的结果集时才能看出这些规则的效果。这个表中的值是数据类型优先顺序的例子。
| PriKey | VariantCol |
| 1 | 50.0(基本类型 float) |
| 2 | 5000(基本类型 int) |
| 3 | '124000'(基本类型 char(6)) |
这是 SELECT * FROM VariantTest ORDER BY VariantCol ASC 语句的结果。
| PriKey | VariantCol |
| 3 | '124000'(基本类型 char(6)) |
| 2 | 5000(基本类型 int) |
| 1 | 50.0(基本类型 float) |
这个表中的值是使用不同的排序规则时有关排序规则优先顺序的例子。
| IntKey | VariantCol |
| 1 | qrs (varchar SQL_Latin1_General_Pref_Cp1_CI_AS) |
| 2 | abc (varchar SQL_Latin1_General_Pref_Cp1_CI_AS) |
| 3 | qrs (varchar SQL_Latin1_General_CP1_CS_AS) |
| 4 | 17.5 (decimal) |
| 5 | abc (varchar SQL_Latin1_General_CP1_CS_AS) |
| 6 | klm (varchar SQL_Latin1_General_CP1_CS_AS) |
| 7 | 1,2 (decimal) |
这是 SELECT * FROM CollateTest ORDER BY VariantCol 语句的结果。下表显示的是组合在一起的来自确定数字数据类型系列的值和在各自的排序规则中组合的 varchar 值。
| IntKey | VariantCol |
| 5 | abc (varchar SQL_Latin1_General_CP1_CS_AS) |
| 6 | klm (varchar SQL_Latin1_General_CP1_CS_AS) |
| 3 | qrs (varchar SQL_Latin1_General_CP1_CS_AS) |
| 2 | abc (varchar SQL_Latin1_General_Pref_Cp1_CI_AS) |
| 1 | qrs (varchar SQL_Latin1_General_Pref_Cp1_CI_AS) |
| 7 | 1,2 (decimal) |
| 4 | 17.5 (decimal) |
当指定 sql_variant 参数时,下面的 Transact-SQL 函数支持 sql_variant 参数并返回 sql_variant 值:
这些函数支持引用 sql_variant 列或变量并且不使用 sql_variant 作为它们返回值的数据类型。
| COL_LENGTH | DATALENGTH | TYPEPROPERTY |
| COLUMNPROPERTY | ISNULL |
这些 Transact-SQL 函数不支持 sql_variant 参数。
| AVG | RADIANS | STDEV[P] |
| IDENTITY | ROUND | SUM |
| ISNUMERIC | SIGN | VAR[P] |
| POWER |
CAST 和 CONVERT 函数支持 sql_variant。
新函数 SQL_VARIANT_PROPERTY():用来得到关于 sql_variant 值的属性信息,例如数据类型、精度和小数位数。
在 LIKE 谓词中不支持sql_variant 列。
在全文本索引中不支持 sql_variant 列。它们不能在全文本函数(例如 CONTAINSTABLE 和 FREETEXTTABLE)中指定。
这些 Transact-SQL 语句支持在指定其它整型数据类型相同的语法位置上指定 sql_variant:
Microsoft® SQL Server™ 2000 目录组件报告有关 sql_variant 列的信息。
如果任何输入和结果表达式的值是 sql_variant,则 CASE 表达式的结果就是 sql_variant。结果的基础数据类型是运行时所求得的表达式的基础数据类型。
数字或字符串串联的运算符不能是 sql_variant:
-- Generates an error:
SELECT VariantCol + @CharacterVar
FROM MyTable
转换 sql_variant 操作数可以执行下面的操作:
-- Does not generates an error:
SELECT CAST(VariantCol AS varchar(25)) + @CharacterVar
FROM MyTable
如果应用程序要求一个结果集,其中一个给定列返回具有单一的基本数据类型的 sql_variant 数据,则该应用程序可以在 Transact-SQL 语句中用 CAST 或 CONVERT 函数通过使用基本数据类型返回 sql_variant 数据。在这种情况下,应用程序处理数据的方式与它处理基本数据类型的结果的方式相同。本主题描述 Microsoft® SQL Server™ 如何返回尚未投影或未转换为特定基本数据类型的 sql_variant 数据。
用于 SQL Server 的 OLE DB 提供程序引入了一个提供程序专用的 OLE DB 类型 DBTYPE_SQLVARIANT,用于 sql_variant 列和参数。
SQL Server ODBC 驱动程序引入了一个提供程序专用的 ODBC 数据库数据类型 SQL_SS_VARIANT,用于 sql_variant 列和参数。
当与连接到下列接口的应用程序一起工作时,SQL Server 将 sql_variant 数据转换成 nvarchar(4000):
如果所得到的字符串超过 4000 个字符,则 SQL Server 返回前 4000 个字符。
当与连接到下列接口的应用程序一起工作时,SQL Server 将 sql_variant 值转换成 varchar(255):
如果所得到的字符串超过 255 个字符,则 SQL Server 返回前 255 个字符。