SQL Server のデータ型の優先順位と注意点
SQL Server のデータ型の優先順位と注意点について
SQL Server のデータ型には「優先順位」というものがあります。
そして、それを知っていないとエラーになってしまうような場面もたまにあります。
この記事では、SQL Server のデータ型の優先順位と注意点などをご紹介します。
SQL Server のデータ型の優先順位
SQL Server では、違うデータ型の値を比較したり、演算したりする際には、データ型を暗黙的に変換してそろえてから処理を行います。
暗黙的にデータ変換をする際には、データ型の優先順位に従って、一番優先順位の高いデータ型に変換されます。
SQL Server では、次のデータ型の優先順位が使用されます。
優先順位 | データ型 |
---|---|
1 | ユーザー定義データ型 |
2 | json |
3 | sql_variant |
4 | xml |
5 | datetimeoffset |
6 | datetime2 |
7 | datetime |
8 | smalldatetime |
9 | date |
10 | time |
11 | float |
12 | real |
13 | decimal |
14 | money |
15 | smallmoney |
16 | bigint |
17 | int |
18 | smallint |
19 | tinyint |
20 | bit |
21 | ntext |
22 | text |
23 | image |
24 | timestamp |
25 | uniqueidentifier |
26 | nvarchar |
27 | nchar |
28 | varchar |
29 | char |
30 | varbinary |
31 | binary |
優先順位の数字が低いほど優先順位が高いという意味で、下のデータ型は自動的に上のデータ型に変換されます。
例えば、INT 型と VARCHAR 型のデータの値を比較する場合は、INT 型の 優先順位が 17 で、VARCHAR 型の優先順位は 28 なので、VARCHAR 型の値が INT 型に変換されます。
それでは、実際に動きを確認してみましょう。
VARCHAR 型と INT 型と DECIMAL 型のデータを LEAST 関数に渡して、一番小さい値を取得してみます。
DECLARE @Value1 VARCHAR(1) = '1', @Value2 INT = 2, @Value3 DECIMAL(8,2) = 3.0; SELECT LEAST(@Value1, @Value2, @Value3) AS LeastValue, SQL_VARIANT_PROPERTY(LEAST(@Value1, @Value2, @Value3), 'BaseType') AS ReturnDataType;
[実行結果]
VARCHAR 型と INT 型と DECIMAL 型の中で一番優先順位が高いのは DECIMAL 型です。
VARCHAR 型と INT 型は DECIMAL 型に暗黙的に変換されて比較され、一番小さい 1.0 が戻り値として返っています。
念の為、LEAST 関数の戻り値を LEASTSQL_VARIANT_PROPERTY
関数を使って確認したところ decimal になっているのがわかります。データ型の優先順位に関連する注意点
データ型の優先順位に関連して注意が必要なことがあります。
まずは、暗黙的に一番優先順位の高いデータ型に変換されるような状況で、変換できない値が存在した場合、データ変換でエラーになってしまうという点です。
例えば、最初に NULL ではない値を返す、COALESCE 関数に、次のようなデータ型の違う引数を渡してみます。
COALESCE 関数の戻り値は、入力引数のデータ型の中で一番優先順位が高いデータ型になります。
DECLARE @Value1 BIT, @Value2 VARCHAR(1) = 'x', @Value3 INT = 3; SELECT COALESCE(@Value1, @Value2, @Value3);
[実行結果]
入力引数のデータ型は BIT 型、VARCHAR 型、INT 型で、一番優先順位が高いデータ型は INT 型です。
最初に NULL ではない値は VARCHAR 型の @Value2 の 'x' で、'x' が INT 型に変換できないため、エラーになっています。
違ったデータ型を指定できる状況でも、入力引数のデータ型をできる限り同じにすることでエラーになる可能性を回避できます。
また、テーブルのカラム側に暗黙のデータ型変換が行われるようなクエリーを書くと、インデックスが有効に使われない場合があり、パフォーマンスに影響が出る可能性があります。
[例] ... WHERE [INT 型のカラム] > @DecimalValue
その他、DECIMAL 型と FLOAT 型の計算では、FLOAT 型のほうが優先順位が高いため、DECIMAL 型が FLOAT 型に変換されて計算されるので、誤差が発生する可能性があります。
データ型の優先順位と暗黙のデータ型変換に注意して、可能な限り暗黙のデータ変換が行われないようなクエリーを書くことをおすすめします。
以上、SQL Server のデータ型の優先順位と注意点などをご紹介しました。