きどたかのブログ

いつか誰かがこのブログからトラブルを解決しますように。

SQLJで壁にぶつかった

やりたいこと:
sqlj.runtime.Scrollableを使って、ResultSetを作って、absoluteメソッドを叩きたい。


現状:
rs.absolute(int)を叩くと例外が出る。


色々やっても全然解決しない。


ログはまずこんな感じで下知を飛ばした。
「TYPE_SCROLL_INSENSITIVEかTYPE_SCROLL_SENSITIVEじゃないとabsoluteは使えないよ」


ResultSet#TYPE_SCROLL_INSENSITIVEとResultSet#TYPE_SCROLL_SENSITIVEのことみたいだ。
(※sqlj側の変数名ではないことを強調したい)


ResultSetを作り出しているのはあくまでResultSetIterImplです。
いやいや、僕らはしっかりとScrollableなイテレータを宣言しているのでそのサブクラスです。
#sql iterator ScrollIter implements sqlj.runtime.Scrollable (String empno, String lastname);


http://publib.boulder.ibm.com/infocenter/db2luw/v9r5/topic/com.ibm.db2.luw.apdv.java.doc/doc/tjvsjscr.html
このページとほぼ同じ書き方をしてる。
いや、全く同じ書き方をしてafeterLastを動かそうとすると、それは例外で終わって動いてくれない。
また、このページの1.において、「デフォルトの sensitivity は INSENSITIVE です。」と書かれているが、
実際にはASENSITIVEが返ってきているようだ。


#sql iterator ScrollIter implements sqlj.runtime.Scrollable with (sensitivity=INSENSITIVE) (String empno, String lastname);
この書き方をすると、以下のエラーがステートメント節あたりの行に出る


SQLJ 変換: Error: Invalid sensitivity WITH value. Detail message: null 合計 1 つのエラー および 1 つの警告.


さらに、dynamicの指定をしてみるともっと酷いのが出る。


#sql iterator ScrollIter implements sqlj.runtime.Scrollable with (sensitivity=INSENSITIVE, dynamic=false) (String empno, String lastname);


SQLJ 変換: Warning: イテレーター属性 dynamic が SQLJ 仕様中に定義されていません。


おいおい、ヒドイじゃないか。
dynamicの指定の例も出てるのに、仕様中に定義されてませんとか言われるんですよ…。


ちなみにどのレベルの仕様かというと、これのはず。これも引用。
SQLJ は ISO/IEC 9075-10:2003 に準拠しています。仕様の日付は 2003/07/25 です。
「Information technology - Database languages - SQL - Part 10: Object Language Bindings (SQL/OLB)
どうやらrevisedされていたらしい。知らなかった。
そして、仕様としてはISO/IEC 9075-10:2008があるようだ。
マジですか・・・、この仕様は本気で進歩してんでしたっけ・・・。


誰か$325で買ってくれませんかね…。僕の専門にしたくないから自腹でこれは買わないよ。



変換は3通り試した。
Linux環境にあるのと同じsqlj.zipおよびdb2jcc4.jarを使って、
sqlj.tools.SqljのmainメソッドにTest.sqljのパスをぶち込む方法。
このSqljバージョンを確認したらIBM SQLJ 3.52.90であった。


ローカルWindows環境に入ってるsqlj4.zipおよびdb2jcc4.jarを使って、
sqlj.tools.SqljのmainメソッドにTest.sqljのパスをぶち込む方法。
このSqljバージョンを確認したらIBM SQLJ 4.2.73であった。


もう一つはローカルWindows環境に入ってるDB2 Express-Cのsqlj.exeを使う方法。
こちらのsqljバージョンはIBM SQLJ 3.52.95であった。
さほど離れていない。


どれも同じ結果となる。
これはプリコンパイラの実装ミスではなかろうか…。




with (sensitivity=INSENSITIVE)を書くか書かないかで、生成されるJavaソースの内容は、
public static intなsensitivityが書かれるか否か程度であった。
事実、.sqljファイルの生成結果でJavaソースにこれを付け加えたらば、僕のやりたいことが動作した。


ちなみに、このURLとほぼ全くと言って良いほど同じメッセージである。
http://dbaspot.com/forums/ibm-db2/83680-db2-udb-8-1-sqlj-precompile-attribute-error.html



また、以下のURLを見ると、v8時代はwith (sensitivity=INSENSITIVE)を書いていた例が、
v9.5のInformation Centerでは記述が無くなっていることも気になる。
http://www.ibm.com/developerworks/data/library/techarticle/0302tsui/0302tsui.html
http://www.ibm.com/developerworks/jp/data/library/dataserver/techdoc/javasqlj.html


SQLJの問題は情報量が少なくて困る。