简体   繁体   English

使用JDBC获取Oracle 11g的最后一个插入ID

[英]Get last insert id with Oracle 11g using JDBC

I'm new to using Oracle so I'm going off what has already been previously answered in this SO question . 我刚开始使用Oracle,所以我将在之前回答过这个问题 I just can't seem to get it to work. 我似乎无法让它工作。 Here's the statement that I'm using: 这是我正在使用的声明:

declare
  lastId number;
begin
INSERT INTO "DB_OWNER"."FOO" 
  (ID, DEPARTMENT, BUSINESS)
  VALUES (FOO_ID_SEQ.NEXTVAL, 'Database Management', 'Oracle')
  RETURNING ID INTO lastId;
end;

When I call executeQuery the PreparedStatement that I have made, it inserts everything into the database just fine. 当我调用executeQuery我所做的PreparedStatement时,它会将所有内容都插入到数据库中。 However, I cannot seem to figure out how to retrieve the ID. 但是,我似乎无法弄清楚如何检索ID。 The returned ResultSet object will not work for me. 返回的ResultSet对象对我不起作用。 Calling 调用

if(resultSet.next()) ...

yields a nasty SQLException that reads: 产生令人讨厌的SQLException,其内容如下:

Cannot perform fetch on a PLSQL statement: next 无法对PLSQL语句执行提取:下一步

How do I get that lastId ? 我怎么得到lastId Obviously I'm doing it wrong. 显然我做错了。

I tried with Oracle driver v11.2.0.3.0 (since there are some bugs in 10.x and 11.1.x, see other blog ). 我尝试使用Oracle驱动程序v11.2.0.3.0(因为10.x和11.1.x中存在一些错误,请参阅其他博客 )。 Following code works fine: 以下代码工作正常:

final String sql = "insert into TABLE(SOME_COL, OTHER_COL) values (?, ?)";
PreparedStatement ps = con.prepareStatement(sql, new String[] {"ID"});
ps.setLong(1, 264);
ps.setLong(2, 1);
int executeUpdate = ps.executeUpdate();
ResultSet rs = ps.getGeneratedKeys();
if (rs.next() ) {
    // The generated id
    long id = rs.getLong(1);
    System.out.println("executeUpdate: " + executeUpdate + ", id: " + id);
}

make it a function that returns it to you (instead of a procedure). 使它成为一个函数,将它返回给你(而不是一个过程)。 Or, have a procedure with an OUT parameter. 或者,使用OUT参数的过程。

Not sure if this will work, since I've purged all of my computers of anything Oracle, but... 不确定这是否有效,因为我已经清除了所有Oracle的计算机,但......

Change your declare to: 将您的声明更改为:

declare
  lastId OUT number;

Switch your statement from a PreparedStatement to a CallableStatement by using prepareCall() on your connection. 通过在连接上使用prepareCall()将语句从PreparedStatement切换到CallableStatement。 Then register the output parameter before your call, and read it after the update: 然后在调用之前注册输出参数,并在更新后读取它:

cstmt.registerOutParameter(1, java.sql.Types.NUMERIC);
cstmt.executeUpdate();
int x = cstmt.getInt(1);

When you prepare the statement set the second parameter to RETURN_GENERATED_KEYS . 准备语句时,将第二个参数设置为RETURN_GENERATED_KEYS Then you should be able to get a ResultSet off the statement object. 然后,您应该能够从语句对象中ResultSet

Are you doing that in a stored procedure ? 你是在存储过程中这样做的吗? According to this Oracle document , it won't work with the server-side driver. 根据此Oracle文档 ,它不适用于服务器端驱动程序。

The Oracle server-side internal driver does not support 
the retrieval of auto-generated keys feature.

You can use Statement.getGeneratedKeys() to do this. 您可以使用Statement.getGeneratedKeys()来执行此操作。 You just need to make sure to tell JDBC what columns you want back using one of the method overloads for that, such as the Connection.prepareStatement overload here: 您只需确保使用其中一个方法重载告诉JDBC您想要返回哪些列,例如此处的Connection.prepareStatement重载:

Connection conn = ...
PreparedStatement pS = conn.prepareStatement(sql, new String[]{"id"});
pS.executeUpdate();
ResultSet rS = pS.getGeneratedKeys();
if (rS.next()) {
  long id = rS.getLong("id");
  ...
}

You don't need to do the RETURNING x INTO stuff with this, just use the basic SQL statement you want. 你不需要用这个来做RETURNING x INTO东西,只需使用你想要的基本SQL语句。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM