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