StoredProcedureResult オブジェクトの OUT および INOUT パラメーター

StoredProcedureResult が戻されると、ストアード・プロシージャーから戻される OUT または INOUT パラメーターの値は、StoredProcedureResultgetOutputParms() メソッドから戻される Object[] に入ります。
StoredProcedureResult オブジェクトは、Data インターフェースのこのバージョンの call() メソッドによって戻されます。
StoredProcedureResult call (java.lang.String sql, Object... parameters)

定位置パラメーターの引き渡し

例えば、2 つの IN Integer パラメーター、1 つの OUT Float パラメーターを持ち、照会結果を戻さないように定義されたストアード・プロシージャーについて考えてみましょう。 以下のようなロジックで呼び出すことができます。

Integer one = new Integer(1);                                                      1 
Integer three = new Integer(3);
Connection con = DriverManager.getConnection(...);                                 2 
Data db = DataFactory.getData(con);                                                3 

StoredProcedureResult spr = db.call("CALL getRatio(?, ?, ?)", one, three, null);   4 
Object[] outputs = spr.getOutputParms();                                           5 
Float oneThird = outputs[2]; // outputs is Object[3]                               6 
spr.close();   // best practice                                                    7 

このコードは、以下のステップを実行します。

  1. IN パラメーターで使用する 2 つの変数を宣言および初期化します。
  2. データベースへの接続を作成します。
  3. Data インターフェースのインプリメンテーションのインスタンスを作成します。
  4. Data.call() メソッドを呼び出して、IN パラメーターの値を渡す CALL ステートメントを実行し、StoredProcedureResult のインプリメンテーションに結果を保管します。
  5. INOUT および OUT パラメーターの値を Object[] 配列に保管します。 IN パラメーターは配列には配置されませんが、NULL プレースホルダーを持っています。
  6. OUT パラメーターの値を Float オブジェクトに保管します。 配列では、最初の 2 つのオブジェクトは IN パラメーターの値になるため、OUT パラメーターの値は 3 番目のオブジェクトになります。
  7. StoredProcedureResult spr と関連付けられたリソースをすべて閉じてから解放します。

疑問符 (?) は定位置パラメーター・マーカーです。最初の疑問符はパラメーター Integer の 1、2 番目の疑問符はパラメーター Integer の 3、そして最後の疑問符はパラメーター NULL にそれぞれ対応します。 NULL 値は、ストアード・プロシージャーの OUT パラメーターの値のプレースホルダーです。

別の例として、SQL メソッド getRatio() に関する情報が一部分しかないと仮定します。 getRatio() メソッドが照会結果を戻さないことがわからず、その IN パラメーターのいずれかが OUT パラメーターにもなるかどうかがわからない場合、ロジックは以下のようになります。

Integer one = new Integer(1);                                                     1 
Integer three = new Integer(3);
Connection con = DriverManager.getConnection(...);                                2 
Data db = DataFactory.getData(con);                                               3 

StoredProcedureResult spr = db.call("CALL getRatio(?, ?, ?)", one, three, null);  4 
Object[] outputs = spr.getOutputParms();                                          5 
for (int j = 0; j < outputs.length; j++)                                          6 
 System.out.println(j + ": " + outputs[j]); 

 while (spr.moveToNext()) {                                                       7 
      ResultSet rsPtr = spr.getResults();
      ...                                                                         8 
   }
}

spr.close();                                                                      9 

このコードは、以下のステップを実行します。

  1. IN パラメーターで使用する 2 つの変数を宣言および初期化します。
  2. データベースへの接続を作成します。
  3. Data インターフェースのインプリメンテーションのインスタンスを作成します。
  4. Data.call() メソッドを呼び出して、IN パラメーターの値を渡す CALL ステートメントを実行し、StoredProcedureResult のインプリメンテーションに結果を保管します。
  5. INOUT および OUT パラメーターの値を Object[] 配列に保管します。 IN パラメーターは配列には配置されませんが、NULL プレースホルダーを持っています。
  6. Object[] 配列の値をプリントします。
  7. ストアード・プロシージャーが照会結果を戻した場合、現在戻されている ResultSet があればそれを閉じてから、次の ResultSet に移動します。
  8. rsPtr によって参照される現在の ResultSet を処理します。
  9. StoredProcedureResult spr と関連付けられたリソースをすべて閉じてから解放します。

Bean でのパラメーターの引き渡し

パラメーターが Bean または Map オブジェクトの Data.call() メソッドに渡されると、ストアード・プロシージャーから返される OUT および INOUT パラメーターの値が Object[] 配列に示され、指定された Bean または Map オブジェクトを更新するために使用されます。

例えば、プロパティー numerator、denominator、および ratio を持つ Bean、Ratio について考えてみましょう。

Integer one = new Integer(1);                                   1 
Integer three = new Integer(3);
Ratio rValue = new Ratio(one, three);                           2 
Connection con = DriverManager.getConnection(...);              3 
Data db = DataFactory.getData(con);                             4 

StoredProcedureResult spr = db.call(
  "CALL getRatio(:numerator, :denominator, :ratio)", rValue);   5 
Float oneThird = rValue.getRatio();                             6 
spr.close();                                                    7 

この例では、:name パラメーター・マーカーの使用は、パラメーターが 1 つだけ存在することを示しています。このパラメーターは Bean ですが、Map オブジェクトであった可能性が同様にあります。

このコードは、以下のステップを実行します。

  1. 2 つの変数 one および three を宣言して初期化します。
  2. 新規 Ratio Bean rValue への参照を宣言して初期化し、one および three をコンストラクターに渡して numerator および denominator の値を提供します。
  3. データベースへの接続を作成します。
  4. Data インターフェースのインプリメンテーションのインスタンスを作成します。
  5. Data.call() のメソッドを呼び出し、rValue を渡す CALL ステートメントを実行します。プロパティー numerator および denominatorIN パラメーターであり、ratioOUT パラメーターです。CALL ステートメントは ratio の値を更新します。
  6. ratio の値を新規の Float oneThird に保管します。
  7. StoredProcedureResult spr と関連付けられたリソースをすべて閉じてから解放します。

マップ・オブジェクトでのパラメーターの引き渡し

プロジェクトのプロジェクト ID および新規終了日に対して DeptProject Bean のプロパティーに 対応する値を渡すことによって、ストアード・プロシージャーを呼び出す場合を想定します。 OUT パラメーターは、その部門プロジェクトに必要な更新済みスタッフ・レベルです。

その目的だけでストアード・プロシージャーを開発することはないかもしれませんが、小さいプロジェクトが大きなプロジェクトに含まれているため、単一プロジェクトの終了日を更新することによって、含まれる複数のプロジェクト間にそれが波及する可能性があります。さらに、その種類のカスケード操作はストアード・プロシージャーにとって適したものになります。 call() メソッドに渡されるパラメーターを DeptProject オブジェクトにすることもできますが、完全にデータが設定されたインスタンスを使用する場合のように、完全にデータを設定するためのものではないオブジェクトを使用することは得策ではありません。 Map オブジェクトは、この種の用途には、より良い選択肢といえます。

この例では、このストアード・プロシージャーの呼び出しは以下のようになります。

Map<String, Object> slipMap;                                             1 

//...                                                                    2 

Connection con = DriverManager.getConnection(...);                       3 
Data db = DataFactory.getData(con);                                      4 

StoredProcedureResult spr = db.call(
  "CALL newEndDate(":projectId, :endDate, :staffLevel)", slipMap );      5 
spr.close();                                                             6 

このコードは、以下のステップを実行します。

  1. 新規の Map slipMap を宣言します。
  2. slipMap 内で projectId および endDate を設定します。
  3. データベースへの接続を作成します。
  4. Data インターフェースのインプリメンテーションのインスタンスを作成します。
  5. Data.call() のメソッドを呼び出し、slipMap を渡す CALL ステートメントを実行します。プロパティー projectId および endDateIN パラメーターであり、staffLevelOUT パラメーターです。CALL ステートメントは staffLevel の値を更新します。
  6. StoredProcedureResult spr と関連付けられたリソースをすべて閉じてから解放します。

フィードバック