今まで動いていたSQLがなぜか動かなくなったという事で、原因を調べていたところ、DB2バージョン9.7からキャスト(CAST)の動作結果が旧バージョン(バージョン9.5以前)と異なることが分かりました。DB2のバージョンを9.1→9.7まで上げたのが原因のようです。
DB2バージョン9.5以降からはスレッドモデルからプロセスモデルに変更されたという情報程度しか入手できていなかったので、そんなの聞いてないし・・・みたいな状態になったのですが、具体的には下記の通りです。
具体例1
下記の表とデータを作成するとします。
CREATE TABLE MY_TAB (C1 DEC(31,2); INSERT INTO MY_TAB VALUES 0.20, 0.02, 1.20, 333.44;
以下のステートメントを実行します。
SELECT CHAR(C1)FROM MY_TAB;
これまでのリリース(バージョン9.5以前)では、以下の結果セットが戻ります。
1 --------------------------------- 00000000000000000000000000000.20 00000000000000000000000000000.02 00000000000000000000000000001.20 00000000000000000000000000333.44
バージョン 9.7 では、以下の結果セットが戻ります。
1 --------------------------------- .20 .02 1.20 333.44
具体例2
以下の表とデータを作成するとします。
CREATE TABLE MY_TAB (C1 DEC(5,0)); INSERT INTO MY_TAB VALUES 1, 4.0;
以下のステートメントを実行します。
SELECT CHAR(C1)FROM MY_TAB;
これまでのリリース(バージョン9.5以前)では、以下の結果セットが戻ります。
1 ----- 0001. 0004.
バージョン 9.7 では、以下の結果セットが戻ります。
1 ----- 1 4
対応策
これまでのリリースのセマンティクスが必要な場合、以下のメソッドを使用できます。
特定の SQL ステートメントを更新し、CHAR() スカラー関数ではなく、CHAR_OLD() スカラー関数を使用します。
データベース構成パラメーター dec_to_char_fmt を ‘V95’ に更新します。 このデータベース構成パラメーターを設定後、CHAR スカラー関数、または 10 進数から文字への CAST 指定を使用する SQL ステートメントを再コンパイルする必要があります。静的 SQL の場合、パッケージを再バインドしなければなりません。動的 SQL の場合には、必要なのはステートメントを呼び出すことだけです。
マイグレーション済みデータベースで新しい形式を使用するには、dec_to_char_fmt を「NEW」に設定します。
結果的にはCastしなくてもいいのでは、という仕様変更です。従来通りの動きを踏襲するにはデータベース構成パラメータの設定を調整するのが一番楽そうです。
その他として、DB2バージョン9.7以降はオートボクシング的な条件文が有効になっています。Decimal関連の変数に文字列を利用した検索などがエラーが出ずに検索できてしまいます。分っていれば良いのですが、知らないと思わぬ動作をしてしまうことがありますので注意が必要です。
コメント