web-dev-qa-db-ja.com

Java(JDBC、プリペアドステートメント)でのOracleのRETURNING INTOの使用法)

JDBCを使用して、次のようなOracleステートメントを実行しています。

"INSERT INTO MYTABLE(MYDATA) VALUES(?) RETURNING MY_CALCULATED_DATA INTO ?"
// MYTABLE's def makes MY_CALCULATED_DATA be auto-generated by DB on insert

私は主にJavaで上記のステートメントを呼び出すいくつかの方法を見つけました:

  • OraclePreparedStatementの使用:

    ps = (OraclePreparedStatement)conn.prepareStatement(sql);
    ps.setString(1, "myvalue");
    ps.registerReturnParameter(2, Types.VARCHAR);
    ps.execute();
    rs = ps.getReturnResultSet();
    rs.next();
    System.out.print(rs.getString(1));
    
  • CallableStatementの使用:

    cs = conn.prepareCall(sql);
    cs.setString(1, "myvalue");
    cs.registerOutParameter(2, Types.VARCHAR);
    cs.execute();
    System.out.print(cs.getString(1));
    

質問:

  1. メソッド#2は "SQLException:すべての戻りパラメーターが登録されているわけではありません"[〜#〜] but [〜#〜] 、SQLステートメントを "BEGIN..END;"-にラップすると、メソッド#2は問題なく機能します。
    • メソッド#1が "BEGIN..END"なしで機能するのに、メソッド#2が機能するには "BEGIN..END"が必要なのはなぜですか?
    • 「すべてのパラメータが登録されていない」問題が突然解決するように、ステートメントに対してどのような「魔法」 "BEGIN..END"を実行しますか?
  2. 上記を行うための3番目のより良い方法はありますか?

ありがとう、AG。

20
Wanna Know All

戻り句で指定されたパラメーターは、通常の出力パラメーターとは異なる方法で処理されるためです(getReturnResultSetとgetResultSetとcallablestatementの戻りパラメーター)。
OraclePreparedStatementで処理する必要があります。 2番目のケースでは、insertステートメントをbegin..endでラップすると、挿入はデータベース自体によって処理され、aljdbcは匿名のplsqlブロックを認識します。
http://docs.Oracle.com/cd/E11882_01/Java.112/e16548/oraint.htm#BABJJDDA

6
mic.sca

自動生成されたキーを取得するには、preparestatementにメソッドgetGeneratedKeysメソッドがあります。このメソッドは、キー値を含む結果セットを返します。必要なのは、キー列名をpreparestatementに渡すことだけです。

pstm = con.prepareStatement("insert query",new String[]{primarykeycolumnname});
int i = pstm.executeUpdate();
if (i > 0) 
{
    ResultSet rs = pstm.getGeneratedKeys();
    while(rs.next())
    {
        System.out.println(rs.getString(1)); 
    }
}
3
Arelli