PL/SQL⇔JDBCメモ
新規に他システムと連携することになった。
そいで関数と引数しかもらえなかったので「(PL/SQL触ったことねぇから)テストユーザくれ」って再三お願いした。
結局リリース当日にやっともらえて本番ぶっつけだった。
そして案の定シクる、と。
ググっても欲しい情報が引っかからなかったからサンプルコード書いてメモっとく。
// 関数: ITEM.IS_AVALABLE // 引数: 商品ID VARCHAR // 戻値: 商品が注文可能かのフラグNUMBER // 0:注文不可 1:注文可 String plsql = "{? = call ITEM.IS_AVALABLE(?)}" // 商品コード String itemCode = "C052-552"; // コネクション取得 Connection conn = ConnectionManager.getConnection(); // ステートメント取得 CallableStatement stmt = conn.prepareCall(plsql); // 一個目の?(戻り値) stmt.registerOutParameter(1, Types.INTEGER); // 二個目の?(引数) stmt.setString(2, itemCode); // クエリ実行 stmt.executeQuery(); // 結果取得 int resultCode = stmt.getInt(1);
●以下、失敗談
:ぶっつけ本番で動作確認とか…
:とりあえず、れっつら起動
:何?FROM句が無いって、「SELECT 1」だけじゃダメなの?
:Oracleでは接続検証用のSQLするなら「SELECT 1 FROM DUAL」ってしなきゃいけないのかー
:DUALてそういやEXISTSの例文で見たな。。。誰でも参照できる空テーブルだっけ(?)
:「パラメータの型が競合します。」 てぇ…んんん?
CallableStatement stmt = conn.prepareCall(plsql); stmt.registerOutParameter(1, Types.INTEGER); stmt.setString(1, itemCode);
:ああ、出力と入力で別のインデックスかと思ってた。戻り値は?の数以降とか?
stmt.registerOutParameter(1, Types.INTEGER); ↓ stmt.registerOutParameter(2, Types.INTEGER);
:「列索引が無効です。」ふんぎゃぁ
String plsql = "{call ITEM.IS_AVALABLE(?)}"
:関数だから、戻り値をセットする場所つくってあげればおk?
String plsql = "{call ITEM.IS_AVALABLE(?)}" ↓ String plsql = "{? = call ITEM.IS_AVALABLE(?)}" stmt.registerOutParameter(1, Types.INTEGER); stmt.setString(2, itemCode);
:キター!!!あとは戻り値をゲトーして、と。
ResultSet rset = stmt.executeQuery(); while (rset.next()) { int resultCode = rset.getInt(1); break; }
:FETCHはいらない…だと…?ああ、複数行帰ってくるわけじゃないしね。
stmt.executeQuery(); int resultCode = stmt.getInt(1);
:やっと動いた…