使用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/