63

当使用带有准备好的语句的 java 查询时,有没有办法从数据库查询中检索自动生成的密钥。

例如,我知道 AutoGeneratedKeys 可以按如下方式工作。

stmt = conn.createStatement();

stmt.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS);
if(returnLastInsertId) {
    ResultSet rs = stmt.getGeneratedKeys();
    rs.next();
    auto_id = rs.getInt(1);
} 

然而。如果我想用准备好的语句进行插入怎么办。

String sql = "INSERT INTO table (column1, column2) values(?, ?)";
stmt = conn.prepareStatement(sql);

//this is an error
stmt.executeUpdate(Statement.RETURN_GENERATED_KEYS);
if(returnLastInsertId) {
    //this is an error since the above is an error
    ResultSet rs = stmt.getGeneratedKeys();
    rs.next();
    auto_id = rs.getInt(1);
} 

有没有办法做到这一点,我不知道。从 javadoc 看来 PreparedStatements 无法返回自动生成的 ID。

4

5 回答 5

99

是的。见这里。第 7.1.9 节。将您的代码更改为:

String sql = "INSERT INTO table (column1, column2) values(?, ?)";
stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);


stmt.executeUpdate();
if(returnLastInsertId) {
   ResultSet rs = stmt.getGeneratedKeys();
    rs.next();
   auto_id = rs.getInt(1);
}
于 2009-09-03T22:12:34.877 回答
4

有几种方法,似乎不同的 jdbc 驱动程序处理的事情有点不同,或者在某些情况下根本没有(有些只会给你自动生成的主键,而不是其他列),但基本形式是

stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); 

或使用这种形式:

String autogenColumns[] = {"column1","column2"};
stmt = conn.prepareStatement(sql, autogenColumns)
于 2009-09-03T22:23:34.790 回答
2

是的,有办法。我刚刚发现它隐藏在 java doc 中。

他们的方法是按如下方式传递 AutoGeneratedKeys id

String sql = "INSERT INTO table (column1, column2) values(?, ?)";
stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
于 2009-09-03T22:16:05.227 回答
2

我是那些浏览了几个线程来寻找这个问题的解决方案的人之一……最终让它发挥作用。对于那些使用 jdbc:oracle:thin: 和 ojdbc6.jar 请注意:您可以使用任何一种方法:(方法 1)

Try{
    String yourSQL="insert into Table1(Id,Col2,Col3) values(SEQ.nextval,?,?)";
    myPrepStatement = <Connection>.prepareStatement(yourSQL, Statement.RETURN_GENERATED_KEYS);
    myPrepStatement.setInt(1, 123); 
    myPrepStatement.setInt(2, 123); 

    myPrepStatement.executeUpdate();
    ResultSet rs = getGeneratedKeys;
    if(rs.next()) {
      java.sql.RowId rid=rs.getRowId(1); 
      //what you get is only a RowId ref, try make use of it anyway U could think of
      System.out.println(rid);
    }
} catch (SQLException e) {
  //
}

(方法二)

Try{
    String yourSQL="insert into Table1(Id,Col2,Col3) values(SEQ.nextval,?,?)";
    //IMPORTANT: here's where other threads don tell U, you need to list ALL cols 
    //mentioned in your query in the array
    myPrepStatement = <Connection>.prepareStatement(yourSQL, new String[]{"Id","Col2","Col3"});
    myPrepStatement.setInt(1, 123); 
    myPrepStatement.setInt(2, 123); 
    myPrepStatement.executeUpdate();
    ResultSet rs = getGeneratedKeys;
    if(rs.next()) {
    //In this exp, the autoKey val is in 1st col
    int id=rs.getLong(1);
    //now this's a real value of col Id
    System.out.println(id);
    }
} catch (SQLException e) {
  //
}

基本上,如果您只想要 SEQ.Nextval 的值,请尝试不使用 Method1,b'cse 它只是返回 RowID 引用,您可能会想办法使用它,这也不适合您尝试转换的所有数据类型它到!这在 MySQL、DB2 中可能工作正常(返回实际 val),但在 Oracle 中不行。

并且,在调试时关闭 SQL Developer、Toad 或任何使用相同登录会话执行 INSERT 的客户端。它可能不会每次都影响你(调试调用)......直到你发现你的应用程序无一例外地冻结了一段时间。是的……毫无例外地停止!

于 2013-06-24T07:39:22.000 回答
-1
    Connection connection=null;
    int generatedkey=0;
    PreparedStatement pstmt=connection.prepareStatement("Your insert query");
    ResultSet rs=pstmt.getGeneratedKeys();
    if (rs.next()) {
       generatedkey=rs.getInt(1);   
               System.out.println("Auto Generated Primary Key " + generatedkey); 
    }
于 2014-03-12T11:32:08.060 回答