使用JDBC连接从oracle返回插入语句的ROWID参数

我似乎无法获得正确的魔法组合来完成这项工作:

OracleDataSource ods = new oracle.jdbc.pool.OracleDataSource(); ods.setURL("jdbc:oracle:thin:app_user/pass@server:1521:sid"); DefaultContext conn = ods.getConnection(); CallableStatement st = conn.prepareCall("INSERT INTO tableA (some_id) VALUES (1) RETURNING ROWID INTO :rowid0"); st.registerReturnParameter(1, OracleTypes.ROWID); st.execute(); 

我得到的错误是“违反协议”。 如果我改为registerOutParameter(),我会收到通知,说明我没有注册所有的返回变量。 如果我将语句包装在PL / SQL中开始; 结束; 然后我使用常规的registerOutParameter()调用得到参数。 我真的更愿意避免在PL / SQL中包装所有的insert语句 – 那么上面缺少什么?

你需要做的一些事情

  • 将CallableStatement更改为OracleCallableStatement
  • 尝试并返回NUMBER,即:OracleTypes.Number

从查询返回信息的示例代码:

 OraclePreparedStatement pstmt = (OraclePreparedStatement)conn.prepareStatement( "delete from tab1 where age < ? returning name into ?"); pstmt.setInt(1,18); /** register returned parameter * in this case the maximum size of name is 100 chars */ pstmt.registerReturnParameter(2, OracleTypes.VARCHAR, 100); // process the DML returning statement count = pstmt.executeUpdate(); if (count>0) { ResultSet rset = pstmt.getReturnResultSet(); //rest is not null and not empty while(rset.next()) { String name = rset.getString(1); ... } } 

有关Oracle JDBC扩展的更多信息:

通常您不希望依赖于代码数据库。 您应该使用CallableStatement而不是OraclePreparedStatement。

 CallableStatement statement = connection.prepareCall("{call INSERT INTO tableA (some_id) VALUES (1) RETURNING ROWID INTO ? }"); statement.registerOutParameter( 1, Types.VARCHAR ); int updateCount = statement.executeUpdate(); if (updateCount > 0) { return statement.getString(1); } 

不知道这是否适用,因为您没有指定您正在使用的版本。

来自Oracle Metalink:

原因

在10.1.0.x JDBC驱动程序中,不支持返回DML:

根据JDBC FAQ:“10.1.0(10g r1)是否支持DML返回?不在当前驱动程序中。但是,我们确实计划在10.1.0之后的驱动程序中支持它。这次我们真的是这个意思。”

由于应用程序代码试图使用不受支持的JDBCfunction,因此会引发错误。

将JDBC驱动程序升级到10.2.0.x,因为根据FAQ,10.2.0.x JDBC驱动程序支持返回子句:

“10.2.0(10g r2)是否支持DML返回?是的!现在是时候了。有关详细信息,请参阅开发人员指南。”

编辑只是为了咧嘴笑,你可以检查Oracle认为它正在使用的JDBC版本:

  // Create Oracle DatabaseMetaData object DatabaseMetaData meta = conn.getMetaData(); // gets driver info: System.out.println("JDBC driver version is " + meta.getDriverVersion()); 

如果它显示了一个JDBC驱动程序10.2.0.x或更高版本,那么我就没有想法了,也许对oracle的支持请求是有序的……

试试用 而不是 SQL字符串上的rowid0 。 我之前遇到过命名参数和Oracle的问题。

 PreparedStatement prepareStatement = connection.prepareStatement("insert...", new String[] { "your_primary_key_column_name" }); prepareStatement.executeUpdate(); ResultSet generatedKeys = prepareStatement.getGeneratedKeys(); if (null != generatedKeys && generatedKeys.next()) { Long primaryKey = generatedKeys.getLong(1); } 

我找到了答案,这完全有效。 我可以从JAVA插入并使用密钥返回它。

完整版本:

 CREATE TABLE STUDENTS ( STUDENT_ID NUMBER NOT NULL PRIMARY KEY, NAME VARCHAR2 (50 BYTE), EMAIL VARCHAR2 (50 BYTE), BIRTH_DATE DATE ); CREATE SEQUENCE STUDENT_SEQ START WITH 0 MAXVALUE 9999999999999999999999999999 MINVALUE 0; 

和Java代码

 String QUERY = "INSERT INTO students "+ " VALUES (student_seq.NEXTVAL,"+ " 'Harry', 'harry@hogwarts.edu', '31-July-1980')"; // load oracle driver Class.forName("oracle.jdbc.driver.OracleDriver"); // get database connection from connection string Connection connection = DriverManager.getConnection( "jdbc:oracle:thin:@localhost:1521:sample", "scott", "tiger"); // prepare statement to execute insert query // note the 2nd argument passed to prepareStatement() method // pass name of primary key column, in this case student_id is // generated from sequence PreparedStatement ps = connection.prepareStatement(QUERY, new String[] { "student_id" }); // local variable to hold auto generated student id Long studentId = null; // execute the insert statement, if success get the primary key value if (ps.executeUpdate() > 0) { // getGeneratedKeys() returns result set of keys that were auto // generated // in our case student_id column ResultSet generatedKeys = ps.getGeneratedKeys(); // if resultset has data, get the primary key value // of last inserted record if (null != generatedKeys && generatedKeys.next()) { // voila! we got student id which was generated from sequence studentId = generatedKeys.getLong(1); } } 

来源: http : //viralpatel.net/blogs/oracle-java-jdbc-get-primary-key-insert-sql/