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 は、対象先にとって大きすぎます。」