JDBC を使用して Oracle DB に対して呼び出されるストアド プロシージャの IN OUT カーソルを処理しようとすると、多くの問題が発生します。以下に、ストアドプロシージャを呼び出して/呼び出して出力を処理する方法を示します。この同じコード (コメントアウトされた部分にわずかな変更を加えたもの) を使用して、インライン SQL 選択ステートメントで同じことを効果的に行うことができますが、理想的には、Java Web サービスの外部で DB の構造と使用法をわかりにくくしたいと考えています。 . さらに、その方法にはパフォーマンスの問題があります。
これは JDBC を IN OUT カーソルで使用して行うことはできないか、JBoss が最終的にこの DataSource 接続を処理する方法に根本的な問題があることを説明している Web に関する非常にあいまいなフォーラム投稿を見つけました (以下の私の更新を参照) )。
呼び出し可能なステートメントの結果をキャストする方法のさまざまな順列に応じて、nullPointerException または次のように表示されます。
「参照カーソルが無効です」
ストアド プロシージャのパラメーターは次のように定義されます。
PROCEDURE "MYSTOREDPROC" (
cursor1 IN OUT MYPACKAGE.MYREFCURSOR,
parm1 IN VARCHAR2,
parm2 IN VARCHAR2) IS
public static final String CALL_TO_STORED_PROCEDURE =
"{ call MYSTOREDPROC(?, ?, ?) }";
conn = getConnection();
stmt = conn.prepareCall(CALL_TO_STORED_PROCEDURE );
// Register the Out Parameter Type (Oracle Cursor)
stmt.registerOutParameter(1, OracleTypes.CURSOR);
// Set the Input Parameters
stmt.setString(2, p1);
stmt.setString(3, p2);
//result = stmt.executeQuery();
stmt.execute();
result = (ResultSet)stmt.getObject(1);
while (result.next()) { // dostuff }
次のような呼び出しを準備する他の方法を試しました。
//stmt = conn.prepareCall(CALL_TO_STORED_PROCEDURE , ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
//stmt = conn.prepareCall(CALL_TO_STORED_PROCEDURE , ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
アップデート:
以下の条件を使用して、接続を Oracle 固有の接続としてキャストし、その接続ハンドルからストアド プロシージャ コールを準備できますが、試行時に(java.sql.SQLException: ORA-01001: 無効なカーソル) を受け取ります。 callable ステートメントの実行結果を参照します。
if(conn instanceof org.jboss.resource.adapter.jdbc.WrappedConnection) {
WrappedConnection wc = (WrappedConnection)conn;
oconn = (oracle.jdbc.OracleConnection)wc.getUnderlyingConnection();
この時点で、私は暗闇の中で揺れているようなものです。これは Jboss 5.1 に完全に関連している可能性がありますか? これを機能させる方法があると想像する必要がありますが、PL/SQLとカーソルの概念についてはほとんど知らず、ここで何がうまくいかないのかさえわかりません。