sql_variant 型のデータの使用
sql_variant データ型の用法は、Microsoft Visual Basic の variant データ型と似ています。sql_variant 型を使用すると、1 つの列、パラメータ、または変数に異なるデータ型のデータ値を格納できるようになります。たとえば、1 つの sql_variant 型の列に、int、decimal、char、binary、および nchar の各型の値を格納できます。sql_variant 型の列の各インスタンスにより、データ値とメタデータ情報が記録されます。この情報には、基本データ型、最大サイズ、小数点以下桁数、有効桁数、および照合順序が含まれます。
sql_variant 型の使用に関する規則
sql_variant データ型を使用するときは、次の規則が適用されます。
通常の値の代入
sql_variant 型のオブジェクトには、任意の SQL Server データ型のデータを格納できます。ただし、text、ntext、image、varchar(max)、nvarchar(max)、varbinary(max)、xml、timestamp の各型、および Microsoft .NET Framework 共通言語ランタイム (CLR) ユーザー定義型は除きます。また、sql_variant データのインスタンスが、sql_variant 型を基本データ型にすることはできません。
すべての型の定数を、sql_variant 型の列を参照する述語または代入で指定できます。
sql_variant 型の値が NULL の場合は、基本データ型がないものと見なされます。この規則は、NULL 値が特定のデータ型を持つ変数または列の値である場合にも適用されます。
次の例では、NULL 値が int 型の変数の値であっても、VariantCol の値はデータ型を関連付けられていない NULL に設定されます。
DECLARE @IntVar int
SET @IntVar = NULL
UPDATE SomeTable SET VariantCol = @IntVar WHERE PriKey = 123
sql_variant 型のオブジェクトから他のデータ型のオブジェクトへの代入では、sql_variant 型の値が代入先のデータ型に明示的にキャストされる必要があります。sql_variant 型の値を別のデータ型のオブジェクトに代入する場合、暗黙的な変換はサポートされません。
他のデータ型との互換性を維持するために、sql_variant 型のオブジェクトの長さを報告するカタログ オブジェクト (DATALENGTH 関数など) により、データの長さが報告されます。sql_variant 型のオブジェクトに格納されたメタデータの長さは返されません。
sql_variant 型の列は、常に ANSI_PADDING が ON の状態で動作します。代入元の ANSI_PADDING が OFF の場合に char、nchar、varchar、nvarchar、または varbinary のいずれかの型の値が代入されると、値への埋め込みは行われません。
サブスクライバ側で 1 つの列を更新すると、別の sql_variant 列で基本データ型が変更されます。次の手順は、この概念を示しています。
マージされたパブリケーションとサブスクリプションを作成します。パブリッシュされたテーブルに sql_variant 列および c1 列を含める必要があります。sql_variant 列にデータを追加します。データの基本データ型は datetime です。
初期同期後も、サブスクライバ側の基本データ型は datetime のままです。
サブスクライバで列 c1 を更新します。
パブリッシャ側の sql_variant 列のデータが datetime2 に変更されます。
テーブル内の sql_variant 型
sql_variant 型の列は、キー列のデータの長さが 900 バイトを超えない限り、インデックスと一意キーで使用できます。
sql_variant 型の列では IDENTITY プロパティがサポートされませんが、主キーまたは外部キーの一部として sql_variant 型の列を使用できます。
sql_variant 型の列は、計算列では使用できません。
ALTER TABLE を使用して、text、ntext、image、timestamp、sql_variant の各型を除く任意のデータ型の列を sql_variant 型に変更します。既存のすべての値が、ALTER TABLE ステートメントを実行する前の列のデータ型と同じ基本データ型を持つ sql_variant 型の値に変換されます。ALTER TABLE を使用して、sql_variant 型の列のデータ型を他のデータ型に変更することはできません。これは、sql_variant 型から他のデータ型への暗黙的な変換がサポートされていないためです。
照合順序
COLLATE 句を使用して、列の照合順序を sql_variant 型の列に割り当てることはできません。sql_variant 型の列の文字ベースの値 (char、nchar、varchar、および nvarchar の各型) の照合順序には、任意の照合順序を指定できます。また、1 つの sql_variant 型の列には、照合順序の異なる文字ベースの値を保持できます。
ある値が sql_variant 型のインスタンスに代入されるときは、代入元のデータ値と基本データ型の両方が代入されます。代入元の値に照合順序がある場合は、その照合順序も代入されます。代入元の値にユーザー定義データ型がある場合は、ユーザー定義データ型ではなく、ユーザー定義データ型の基本データ型が代入されます。sql_variant 型のインスタンスでは、ユーザー定義データ型にバインドされた規則または既定値は継承されません。IDENTITY プロパティを持つ列の値が sql_variant 型のインスタンスに代入された場合、sql_variant 型の基本データ型は代入元の列の基本データ型になりますが、IDENTITY プロパティは継承されません。これは、text、ntext、または image のいずれかの型の値を sql_variant 型のインスタンスに代入するときのエラーです。他のデータ型のオブジェクトの値を sql_variant 型のオブジェクトに代入する場合は、暗黙的な変換がサポートされます。
sql_variant 型の比較
sql_variant 型の列には複数の基本データ型と照合順序の値を格納できるため、sql_variant 型のオペランドを比較するときには、特別な規則が適用されます。これらの規則は、次のような比較を行う場合に適用されます。
Transact-SQL 比較演算子
ORDER BY、GROUP BY
インデックス
集約関数 MAX と MIN
UNION (ALL 以外)
CASE 式
sql_variant 型の比較のために、SQL Server のデータ型階層の順序は、データ型ファミリにグループ化されます。ファミリの優先順位が最も高いのは、sql_variant ファミリです。
データ型階層 |
データ型ファミリ |
---|---|
sql_variant |
sql_variant |
datetime |
日付と時刻 |
smalldatetime |
日付と時刻 |
Float |
概数値 |
Real |
概数値 |
decimal |
正確な数値 |
money |
正確な数値 |
smallmoney |
正確な数値 |
bigint |
正確な数値 |
int |
正確な数値 |
smallint |
正確な数値 |
tinyint |
正確な数値 |
bit |
正確な数値 |
nvarchar |
Unicode |
nchar |
Unicode |
varchar |
Unicode |
char |
Unicode |
varbinary |
バイナリ |
binary |
バイナリ |
uniqueidentifier |
一意識別子 |
sql_variant 型の比較には、次の規則が適用されます。
基本データ型の異なる sql_variant 型の値どうしを比較するときに、両者の基本データ型が異なるデータ型ファミリに属する場合は、階層表内で上位にあるデータ型ファミリの値の方が、両者間ではより高い値であると見なされます。
基本データ型が異なる sql_variant 型の値どうしを比較するときに、両者の基本データ型が同じデータ型ファミリに属する場合は、階層表内で下位にある基本データ型の値の方が、暗黙的に他方のデータ型に変換され、その後比較が行われます。
char、varchar、nchar、または varchar のいずれかのデータ型の sql_variant 型の値どうしを比較する場合、それらの値は、LCID、LCID のバージョン、比較フラグ、および並べ替え ID という基準に基づいて評価されます。これらの基準は、ここで列挙した順番に従って、それぞれ整数値として比較されます。
上記の規則により、sql_variant 型どうしの値を比較する場合に、同じ基本データ型の値どうしの比較とは異なる結果が生じる場合があります。
オペランド A |
オペランド B |
バリアント型以外の比較結果 |
sql_variant 型の比較結果 |
---|---|---|---|
'123' char |
111 int |
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 型の値が返されます。
COALESCE |
MIN |
MAX |
NULLIF |
次の関数では、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 型の値に関するプロパティ情報を取得できます。
その他の Transact-SQL 要素と sql_variant 型のデータ
sql_variant 型の列は、LIKE 述語ではサポートされません。
sql_variant 型の列は、フルテキスト インデックスではサポートされません。CONTAINSTABLE や FREETEXTTABLE などのフルテキスト関数では、sql_variant 型の列を指定できません。
次の Transact-SQL ステートメントでは、構文中の他の整数データ型を指定した位置と同じ位置に sql_variant 型を指定することがサポートされます。
ALTER PROCEDURE
ALTER TABLE
CREATE PROCEDURE
CREATE TABLE
DECLARE variable
SQL Server のカタログ コンポーネントにより、sql_variant 型の列に関する情報が報告されます。
CASE 式の結果は、入力式または結果式のいずれかの評価結果が sql_variant 型である場合、sql_variant 型になります。結果の基本データ型は、実行時に結果として評価された式の型になります。
数値または文字列の連結演算子のオペランドを sql_variant 型にすることはできません。たとえば、次のコードを実行するとエラーが発生します。
SELECT VariantCol + @CharacterVar
FROM MyTable
ただし、次のように sql_variant 型のオペランドをキャストすることにより、この演算を実行できます。
SELECT CAST(VariantCol AS varchar(25)) + @CharacterVar
FROM MyTable
アプリケーションと sql_variant 型のデータ
単一の基本データ型を持つ sql_variant 型のデータを特定の列が返すような結果セットをアプリケーションが要求する場合、このアプリケーションは Transact-SQL ステートメントで CAST 関数または CONVERT 関数を使用し、その基本データ型を使用して sql_variant 型のデータを返すことができます。この場合、基本データ型の結果セット列と同様の方法でデータが扱われます。
SQL Server Native Client OLE DB Provider for SQL Server により、sql_variant 型の列とパラメータで使用できるプロバイダ固有の OLE DB 型である DBTYPE_SQLVARIANT が導入されています。
SQL Server の SQL Server Native Client ODBC ドライバにより、sql_variant 型の列とパラメータで使用できるプロバイダ固有の ODBC データベースのデータ型である SQL_SS_VARIANT が導入されています。
次のインターフェイスを使用して接続したアプリケーションで作業する場合は、SQL Server により、sql_variant 型の値が nvarchar(4000) 型に変換されます。
SQL Server 7.0 の OLE DB プロバイダ。
SQL Server 7.0 の SQL Server ODBC ドライバ。
結果の文字列が 4,000 文字を超える場合は、最初の 4,000 文字が SQL Server によって返されます。
次のインターフェイスを使用して接続したアプリケーションで作業する場合は、SQL Server により、sql_variant 型の値が varchar(255) 型に変換されます。
- SQL Server 6.5 以前の SQL Server ODBC ドライバ。
結果の文字列が 255 文字を超える場合は、最初の 255 文字が SQL Server によって返されます。