Saving different types in one column with SQL_VARIANT is almost the same as everything you need to do for Object in .NET. And sometimes there are good reasons for using this type, since it can certainly make it possible to create a more general program structure.
However, as you expected, there are some problems with using SQL_VARIANT that you should be aware of, especially since one of them may be an unlocker:
Just like giving all Object in .NET (and possibly requiring boxing / unpacking depending on the base type), there is a certain performance improvement when using SQL_VARIANT . Depending on the use case, performance degradation may be acceptable if the functionality really needs it and / or use is not very common (i.e. many times per second).
Unlike all Object tags in .NET, the SQL_VARIANT data type has restrictions on what underlying data types can contain. The following data types cannot be saved as SQL_VARIANT :
VARCHAR(MAX)NVARCHAR(MAX)VARBINARY(MAX)XMLTIMESTAMP / ROWVERSIONTEXT (you should not use this type anyway with SQL Server 2005)NTEXT (you should not use this type anyway with SQL Server 2005)IMAGE (you should not use this type anyway with SQL Server 2005)
This restriction can easily prevent the possibility of using SQL_VARIANT if there is a requirement to store any of these data types. Note that the problem here is the underlying data type, not the data size, as the following test shows:
DECLARE @tmp1 TABLE (col1 SQL_VARIANT NOT NULL); INSERT INTO @tmp1 (col1) VALUES (CONVERT(VARCHAR(MAX), 'g'));
Return:
Msg 206, Level 16, State 2, Line 2 Operand type clash: varchar(max) is incompatible with sql_variant
To be fair, one of the advantages of using SQL_VARIANT over NVARCHAR is that SQL_VARIANT stores information about the base type and applies its use, so you cannot easily abuse values ββin completely inappropriate contexts.
DECLARE @tmp2 TABLE (col1 SQL_VARIANT NOT NULL); INSERT INTO @tmp2 (col1) VALUES (1); SELECT CONVERT(DATETIME, col1) FROM @tmp2; SELECT CONVERT(TIME, col1) FROM @tmp2;
Return:
1900-01-02 00:00:00.000 Msg 529, Level 16, State 3, Line 6 Explicit conversion from data type int to time is not allowed.
Regarding the inability to use SQL_VARIANT as a PC: this is really not a problem, since the nature of the general data type largely excludes it from the desire primarily for such use.
Regarding the fact that you cannot use SQL_VARIANT with the LIKE operator: this is basically not a problem, because it can convert it to the corresponding type that works with LIKE , as in:
WHERE CONVERT(NVARCHAR(50), [sql_variant_field]) LIKE '%something%'
The above, of course, is not the most efficient, but it is functional, and, as mentioned above, efficiency is already ruled out, since it was sacrificed for functionality when deciding to use the SQL_VARIANT data type.