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'
goType
-----------------------------------------
int
select SQL_VARIANT_PROPERTY(2147483648,'BaseType') as 'Type'
goType
-----------------------------------------
numeric
※ numeric と decimal は等価です。
int、bigint、smallint、および tinyint (Transact-SQL)