SQL Server における数値定数 2147483647 と 2147483648 の違い

 

神谷 雅紀
SQL Server Escalation Engineer

 

小数点記号 “.” なしの整数は、通常は int と解釈されますが、int のデータ範囲 (-2^31 (-2147483648) ~ 2^31-1 (2147483647)) を超える値は bigint ではなく numeric として解釈されます。

この違いは、通常あまり意識されることはないと思いますが、データ型不一致の問題や算術オーバーフローなどを発生させる可能性がありますので、cast や convert 関数、パラメーター化クエリのパラメーターとして明示的にデータ型を指定するなどの考慮が必要です。

例えば、以下の最初の式は「メッセージ 8115、レベル 16、状態 2、expression をデータ型 int に変換中に、算術オーバーフロー エラーが発生しました。」となりますが、二つ目は計算結果 2147483649 を返します。三つ目のように明示的にデータ型を指定すれば、2147483647+1 もエラーにはなりません。

 

-- エラー 8115 になる。
select 2147483647+1

-- 2147483649 が返される。     
select 2147483648+1

-- 2147483648 が返される。
select cast(2147483647 as bigint)+1

 

定数のデータ型は以下の方法で確認することができます。

 

select SQL_VARIANT_PROPERTY(2147483647,'BaseType') as 'Type'
go

Type
-----------------------------------------
int

 

select SQL_VARIANT_PROPERTY(2147483648,'BaseType') as 'Type'
go

Type
-----------------------------------------
numeric

 

※ numeric と decimal は等価です。

 

int、bigint、smallint、および tinyint (Transact-SQL)

https://msdn.microsoft.com/ja-jp/library/ms187745.aspx