【问题标题】:Is there a way to retrieve the autoincrement ID from a prepared statement有没有办法从准备好的语句中检索自动增量 ID
【发布时间】:2010-11-25 11:05:20
【问题描述】:

在使用带有准备好的语句的 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。

【问题讨论】:

  • returnLastInsertId 你从哪里得到这个变量

标签: java mysql prepared-statement auto-increment


【解决方案1】:

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

【讨论】:

  • @JafarAli,这个问题是关于 mysql 的。在 oracle 中,您必须指定 the generated column 或使用行 ID。
  • 你忘记rs.close()了吗?有必要吗?
  • @Winter,这段代码专注于解决问题中的问题,而不是处理资源和异常处理。像任何其他语句和结果集一样,调用 close 是必要的。
  • @Winter,如果你的键是长的,那么在最后调用 rs.getLong(1)。
【解决方案2】:

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

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

或者使用这种形式:

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

【讨论】:

    【解决方案3】:

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

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

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

    【讨论】:

      【解决方案4】:

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

      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 ref,您可能会想方设法使用它,它也不适合所有数据类型您尝试将其投射到!这在 MySQL、DB2 中可能工作正常(返回实际 val),但在 Oracle 中不行。

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

      【讨论】:

      • executeUpdate() 不返回ResultSet,而是返回int,即更新计数。您必须单独检索生成的密钥。请参阅现有答案,以及看在上帝的份上的 Javadoc。 -1。 Again. 请不要在这里发布您未经测试的猜测。
      【解决方案5】:
          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); 
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-07-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-26
        相关资源
        最近更新 更多