DB2_COMPATIBILITY_VECTORを設定する前に・・


日ごろから、DB2_COMPATIBILITY_VECTORについて、
「設定するといいよ」を言いまくっていましたが
各フラグによっては、動くが変わるものがあるので
吟味しながら設定をかけたほうがよいようです。

っていうか、見事にハマったので、そのはまり具合のご報告になります。


DB2_COMPATIBILITY_VECTORレジストリ変数は、
DB2においていろいろ便利になったり、某青山方面な機能を使えたりする設定で
有名どころではrownum()関数が使えるようになったりします。
DB2 9.5では裏コマンド的な公開でしたが、
Ver9.7ではちゃんとInformation Centerで公開されています。
http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/topic/com.ibm.db2.luw.apdv.porting.doc/doc/r0052867.html


このDB2_COMPATIBILITY_VECTORレジストリ変数は、設定した際は
インスタンスを再起動しないといけないので、早々インスタンスの再起動が
出来ないのなら、インストール時やマイグレーション時に設定を
しておくほうがよいと考えていました。


ですが、実はこの考えは浅はかだったかも知れないのです、、
そのはまりポイントは

6 (0x20) 	VARCHAR2 データ・タイプ 1 	VARCHAR2 データ・タイプおよび関連する文字ストリング処理を有効にします。

にありました。



たとえば
DB2_COMPATIBILITY_VECTORには値がセットされていない
または20が含まれていない状態でインスタンスが上がっていたときにDBを作成し、
NOT NULL属性を付与した列があるテーブルを作成し、
その列に''をインサートしようとした場合、インサートできます。

$ db2 create db TESTTES1
DB20000I  The CREATE DATABASE command completed successfully.

$ db2 connect to TESTTES1

   Database Connection Information

 Database server        = DB2/LINUX 9.5.3
 SQL authorization ID   = DB2INST1
 Local database alias   = TESTTES1

$ db2 "create table testtable1 (data VARCHAR(10) not null)"
DB20000I  The SQL command completed successfully.

$ db2 "insert into testtable1 (data) values ('')"
DB20000I  The SQL command completed successfully.

DB2_COMPATIBILITY_VECTORを設定してインスタンスを立ち上げなおし、
同様にテーブルをつくりinsertをすると、SQL0407Nが発生します。

$ db2set DB2_COMPATIBILITY_VECTOR=20

$ db2 connect reset 
DB20000I  The SQL command completed successfully.
$ db2stop
SQL1064N  DB2STOP processing was successful.
$ db2start
SQL1063N  DB2START processing was successful.

$ db2 create db TESTTES2
DB20000I  The CREATE DATABASE command completed successfully.


$ db2 connect to TESTTES2

   Database Connection Information

 Database server        = DB2/LINUX 9.5.3
 SQL authorization ID   = DB2INST1
 Local database alias   = TESTTES2

$ db2 "create table testtable2 (data VARCHAR(10) not null)"
DB20000I  The SQL command completed successfully.

$ db2 "insert into testtable2 (data) values ('')"
DB21034E  The command was processed as an SQL statement because it was not a 
valid Command Line Processor command.  During SQL processing it returned:
SQL0407N  Assignment of a NULL value to a NOT NULL column "TBSPACEID=2, 
TABLEID=4, COLNO=0" is not allowed.  SQLSTATE=23502

この状態(DB2_COMPATIBILITY_VECTORが20)で、先に作ったDBに接続しなおして
insertを実行するとちゃんと入ってくれます。

$ db2 connect reset 
DB20000I  The SQL command completed successfully.

$ db2 connect to TESTTES1
$ db2 "insert into testtable1 (data) values ('')"
DB20000I  The SQL command completed successfully.


また、DB2_COMPATIBILITY_VECTORの値を消して、インスタンスを再起動しても
後に作ったDBのテーブルにinsertしても、エラーは出続けます。

$ db2set DB2_COMPATIBILITY_VECTOR=

$ db2 connect reset 
DB20000I  The SQL command completed successfully.

$ db2stop
SQL1064N  DB2STOP processing was successful.

$ db2start
SQL1063N  DB2START processing was successful.

$  db2 connect to TESTTES2

   Database Connection Information

 Database server        = DB2/LINUX 9.5.3
 SQL authorization ID   = DB2INST1
 Local database alias   = TESTTES2

$ db2 "insert into testtable2 (data) values ('')"
DB21034E  The command was processed as an SQL statement because it was not a 
valid Command Line Processor command.  During SQL processing it returned:
SQL0407N  Assignment of a NULL value to a NOT NULL column "TBSPACEID=2, 
TABLEID=4, COLNO=0" is not allowed.  SQLSTATE=23502

いろいろやってるときは結構頭のなかごっちゃごちゃになったのですが
実はこれらのことは
http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/topic/com.ibm.db2.luw.apdv.porting.doc/doc/r0052880.html

長さがゼロである文字ストリング値 (LOB 値以外) は、通常は NULL 値として処理されます。CHAR または VARCHAR に空ストリング値を割り当てるかキャストすると、NULL 値が生成されます。

と出ていますし、リードにも

VARCHAR2 はデータベース・レベルでサポートされるため、サポートが必要なデータベースを作成する前に有効にする必要があります。
その場合は、DB2_COMPATIBILITY_VECTOR レジストリー変数に適切な値を設定します。VARCHAR2 サポートを有効にしてデータベースを作成すると、データベース構成パラメーター varchar2_compat が ON に設定されます。
VARCHAR2 のサポートを有効にしてデータベースを作成した場合は、DB2_COMPATIBILITY_VECTOR レジストリー変数をリセットしても、そのデータベースについて VARCHAR2 のサポートを無効にすることはできません。
同様に、VARCHAR2 のサポートを無効にして作成されたデータベースでは、DB2_COMPATIBILITY_VECTOR レジストリー変数を設定しても、VARCHAR2 のサポートを有効にすることはできません。

と説明が出ているので、仕様といえば仕様。


ということで、便利になるからといってDB2_COMPATIBILITY_VECTORをフルセットしてしまうと
何が原因かわからず悩まされ手しまうハメになるかもです。。
(というか、自分は間違いなくハマりました・・)


このように、今までの考え方でうごくはずのものが、
DB2_COMPATIBILITY_VECTORの設定後に作られたDBに関しては
振る舞いが変わる可能性があります。


もちろん、ROWNUMやTRUNCATE TABLE、データ・ディクショナリー互換ビューなどは
運用していく上で便利な機能ではありますが
DB2_COMPATIBILITY_VECTORの設定値はドキュメントをみて、
実際にテストサーバで振る舞いを確認し、
吟味した後に設定対応したほうがいいかもしれません。

6 (0x20) 	VARCHAR2 データ・タイプ 1 	VARCHAR2 データ・タイプおよび関連する文字ストリング処理を有効にします。

以外にも

5 (0x10) 	NUMBER データ・タイプ 1 	NUMBER データ・タイプおよび関連する数値処理を有効にします。
7 (0x40) 	DATE データ・タイプ 1 	DATE データ・タイプを日付と時間の値を結合した TIMESTAMP(0) として使用することを可能にします。

は危険かも・・
http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/topic/com.ibm.db2.luw.apdv.porting.doc/doc/r0052867.html


ということで、ORAする前に一考を・・