スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
拍手コメントを見る

MS SQL の SqlException

SQL で次のエラーがでた。

「numeric をデータ型 numeric に変換中に、算術オーバーフローエラーが発生しました。」

エラーがでた SQL 文のサンプルは次の通り。

SELECT ISNULL( decVal1, decVal2 * 5 ) FROM Table_Hoge

decVal1 および、decVal2 のデータ型は、どちらも DECIMAL(5,2)。
エラーが起こった行の decVal1 は NULL で、devVal2 は 200.00 だった。

devVal2 * 5 は、1000.00 になる。

ちなみに次の式ではエラーにならない。

SELECT decVal2 * 5 FROM Table_Hoge.

エラーの意味がわからなくて、ややパニック。何でエラーになるの?
ここで、SQL関数の ISNULL( arg1, arg2 ) の仕様を考える必要があった。

ISNULL( arg1, arg2 ) は、arg1 が NULL の場合、arg2 の値を、arg1 の「型」に代入するというもの。

つまり先の実例では、1000.00 を decVal1 に代入している事になる。
decVal1 のデータ型は繰り返しになるが、DECIMAL(5,2)。全部で5桁のうち、3桁が整数部分で、2桁が小数点以下という宣言。

そう、1000.00 は、整数部分が4桁になるのである。だからオーバーフローエラーが発生するのだ。

解決策として取った方法は、次のとおり。

SELECT ISNULL( CAST( decVal1 AS DECIMAL(7,2) ), decVal2 * 5 ) FROM Table_Hoge

要するに、代入先の型を CAST して DECIMAL(7,2) として拡張したのである。

整数部を2桁分増やしただけなので、もちろん、decVal2 の値が 20000.00 以上になった場合、同じオーバーフローエラーがでることになる。

そもそも、decVal2 には、200なんて数字が入る事を想定していなかったが、この値をテーブルに登録する側は、そんなことは考えて作られていなかった。

本来ならば、利用する側ではなく、登録する側でエラーチェックを行い、イリーガルなデータを登録させないようにするべきだとは思うのだけれど、異常系を考慮すると、利用する側にも防衛線を張っておく必要がある、というのが双方の着地点というか妥協点になる。 拍手コメントを見る

コメント

非公開コメント
ブログ内検索
プロフィール

雷ぶ

Author:雷ぶ

最近の記事
最近のコメント
最近のトラックバック
カテゴリー
月間アーカイブ
ブロとも申請フォーム

この人とブロともになる

RSSフィード
リンク

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。