Java 使用到oracle的JDBC连接从insert语句返回ROWID参数
我似乎找不到合适的魔法组合来实现这一点:Java 使用到oracle的JDBC连接从insert语句返回ROWID参数,java,oracle,jdbc,Java,Oracle,Jdbc,我似乎找不到合适的魔法组合来实现这一点: 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
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 begin中;结束;块,然后使用常规的registerOutParameter()调用获得参数。我真的希望避免将所有inserts语句包装在PL/SQL中—那么上面缺少了什么?尝试在SQL字符串上使用?而不是:rowid0。我以前在命名参数和Oracle方面遇到过问题。不知道这是否适用,因为您没有指定使用的版本 从Oracle Metalink: 原因 在10.1.0.x JDBC驱动程序中,不支持返回DML: 根据JDBC常见问题解答: “10.1.0(10g r1) 是否支持DML返回? 不是在当前的驱动程序中。但是,我们有计划在10.1.0后的驱动程序中支持它。我们 这次是认真的。” 当应用程序代码试图使用不受支持的JDBC特性时,会出现错误 解决方案 将JDBC驱动程序升级到10.2.0.x,因为根据常见问题解答,10.2.0.x JDBC驱动程序确实支持returning子句: “10.2.0(10g r2) 是否支持DML返回? 是的!是时候了。有关详细信息,请参阅《开发人员指南》。” 编辑 对于grins,您可以检查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请求支持…您需要做一些事情
- 将CallableStatement更改为OracleCallableStatement
- 尝试返回一个数字,即: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);
...
}
}
OraclePreparedStatement pstmt=(OraclePreparedStatement)conn.prepareStatement(
“从表1中删除,其中年龄<?将姓名返回?”);
pstmt.setInt(1,18);
/**寄存器返回参数
*在这种情况下,名称的最大大小是100个字符
*/
pstmt.registerReturnParameter(2,OracleTypes.VARCHAR,100);
//处理DML返回语句
count=pstmt.executeUpdate();
如果(计数>0)
{
ResultSet rset=pstmt.getReturnResultSet();//rest不为null且不为空
while(rset.next())
{
String name=rset.getString(1);
...
}
}
有关Oracle JDBC扩展的更多信息:
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);
}
我已经找到了答案,这是完美的作品。我可以从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);
}
}
来源:感谢您提供的信息,以下是我正在使用的各种版本:Java版本:1.6.0_12-b04虚拟机版本:11.2-b01(热点服务器)Oracle服务器:10.2.0.4 Oracle客户端:11.1.0.7.0到ojdbc6.jar这个语法糖正是我所需要的-{call}也为我工作。需要注意的是,如果你有一个IN参数和一个OUT参数,指数总是上升的。因此,如果您执行
{调用INSERT INTO tbl(x,y)值(seq.NEXTVAL),将x返回到}
中,那么seq.NEXTVAL
将在语句中返回。getLong(2)
,而不是getLong(1)
。。
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);
}
}