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

时间:2011-02-10 00:45:59

标签: java oracle jdbc oracle11g

我是使用Oracle的新手,因此我将在this SO question中解决之前已经回答的问题。我似乎无法让它工作。这是我正在使用的声明:

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;

当我调用executeQuery我所做的PreparedStatement时,它会将所有内容都插入到数据库中。但是,我似乎无法弄清楚如何检索ID。返回的ResultSet对象对我不起作用。调用

if(resultSet.next()) ...

产生令人讨厌的SQLException,其内容为:

  

无法在PLSQL语句上执行fetch:next

如何获得lastId?显然我做错了。

6 个答案:

答案 0 :(得分:2)

使它成为一个函数,将它返回给你(而不是一个过程)。或者,使用OUT参数进行过程。

答案 1 :(得分:2)

不确定这是否有效,因为我已经清除了所有Oracle的计算机,但是......

将您的声明更改为:

declare
  lastId OUT number;

使用您的连接上的prepareCall()将语句从PreparedStatement切换到CallableStatement。然后在调用之前注册输出参数,并在更新后读取它:

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

答案 2 :(得分:2)

我尝试使用Oracle驱动程序v11.2.0.3.0(因为10.x和11.1.x中存在一些错误,请参阅other blog)。以下代码工作正常:

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);
}

答案 3 :(得分:1)

准备语句时,将第二个参数设置为RETURN_GENERATED_KEYS。然后你应该能够从语句对象中获得ResultSet

答案 4 :(得分:1)

您是否在存储过程中执行此操作?根据此Oracle document,它不适用于服务器端驱动程序。

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

答案 5 :(得分:1)

您可以使用Statement.getGeneratedKeys()执行此操作。您只需确保使用其中一个方法重载告诉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");
  ...
}

您不需要使用此RETURNING x INTO内容,只需使用您想要的基本SQL语句。