Oracle在Java中的RETURNING INTO使用(JDBC,Prepared Statement)

我正在使用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:并非所有返回参数都已注册”但是 ,如果我将SQL语句包装成“ BEGIN..END; ” – 则方法#2工作正常。
    • 为什么方法#1在没有“ BEGIN..END ”的情况下工作,但方法#2需要“ BEGIN..END ”才能工作?
    • 什么样的“魔术”“ BEGIN..END ”对声明做了什么,以便“不是所有参数注册”问题突然解决了?
  2. 有没有第三种,更好的方法来做上述事情?

谢谢你,AG。

因为与正常输出参数相比,返回子句中指定的参数以不同的方式处理(getReturnResultSet vs getResultSet vs callablestatement中的返回参数)。
它们需要使用OraclePreparedStatement进行处理。 在第二种情况下,当您在begin..end中包装insert语句时,insert将由数据库本身处理,而al jdbc看到的是一个匿名的plsql块。
http://docs.oracle.com/cd/E11882_01/java.112/e16548/oraint.htm#BABJJDDA

要获取自动生成的密钥,我们在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)); } }