有没有办法从预准备语句中检索自动增量ID

时间:2009-09-03 22:04:27

标签: java mysql prepared-statement auto-increment

当使用带有预准备语句的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);
} 

然而。如果我想使用准备好的Statement进行插入,该怎么办?

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。

5 个答案:

答案 0 :(得分:91)

是。见here。第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);
}

答案 1 :(得分:3)

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

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

或使用此表格:

String autogenColumns[] = {"column1","column2"};
stmt = conn.prepareStatement(sql, autogenColumns)

答案 2 :(得分:2)

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

他们的方式是传递AutoGeneratedKeys id,如下所示

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

答案 3 :(得分:2)

我是那些通过几个线程寻找解决这个问题的人之一...并最终让它发挥作用。对于那些使用jdbc:oracle:thin:with 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) {
  //
}

(方法2)

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中却没有。

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

答案 4 :(得分:-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); 
    }