TECHNOLOGY
FAQ (よくある質問)
対象バージョン : 5.5.0.x-9.0.x
対象OS : 全て
QUESTION ( SQ0612068 )
数値演算の結果がおかしい。
(乗算や加算の結果が期待される結果と異なる)
(現象例)
カラム Col1 (Integer) に 2,000,000,000
カラム Col2 (Integer) に 1,000,000,000
という値が保存されているときに
SELECT Col1 + Col2 FROM ~
というクエリを実行すると、
2,000,000,000 + 1,000,000,000 = 3,000,000,000 となるはずですが、
-1,294,967,296 というおかしな結果になります。
ANSWER
原因:
この現象は数値演算のオーバーフローが原因です。
符号付き整数(Integer)同士の計算では、扱える数値の範囲も符号付き整数となりますが、符号付き整数で表現できる値の範囲は、-2^31 ~ 2^31、または -2,147,483,648 ~ 2,147,483,647 です。
この為、この範囲を超える計算が行なわれるとオーバーフローを起こし、正しくない値となります。
なお、この現象は真数値データ型同士の演算でのみ発生します。(概数値データ同士、または真数値データ型と概数値データの演算では発生しません。)
対策:
数値演算では演算対象データの中から、一番大きなデータ型に合わせて演算が行なわれますので、想定される結果の大きさに合わせてデータの型を変更します。
(例)
カラム Col1 (Integer) を Col1 (Bigint) に変更する。
また、対象データのデータ型を変更することができない場合、次のような方法でデータ型のキャストを行い、数値演算のオーバーフローを回避します。
SELECT Cast(Col1 as Bigint) + Col2 FROM ~
キャストの詳細については、以下のオンラインマニュアルをご参照下さい。
ASA SQL リファレンス・マニュアル (9.0.2のマニュアルより)
SQL 関数
アルファベット順の関数リスト
CAST 関数 [データ型変換]
ご参考までに、
通常、ユーザが演算結果の確認を行なわない限り、オーバーフローの発生したことを知ることはできません。
しかし、データベース・オプションの ANSI_INTEGER_OVERFLOW オプション(デフォルト “OFF”)を “ON” に設定することにより、整数演算のオーバーフローが発生した場合、エラーとして報告されるようになります。
「SQLSTATE 22003 : 値 %1 は、対象先にとって大きすぎます。」