2010-11-19 26 views
62

Cách duy nhất mà một số trình điều khiển JDBC để trở Statement.RETURN_GENERATED_KEYS là để làm một cái gì đó trong các cách sau:PreparedStatement với Statement.RETURN_GENERATED_KEYS

long key = -1L; 
Statement statement = connection.createStatement(); 
statement.executeUpdate(YOUR_SQL_HERE, Statement.RETURN_GENERATED_KEYS); 
ResultSet rs = statement.getGeneratedKeys(); 
if (rs != null && rs.next()) { 
    key = rs.getLong(1); 
} 

Có cách nào để làm điều tương tự với PreparedStatement?


Sửa

Lý do tôi hỏi nếu tôi có thể làm tương tự với PreparedStatement xem xét các tình huống sau:

private static final String SQL_CREATE = 
      "INSERT INTO 
      USER(FIRST_NAME, MIDDLE_NAME, LAST_NAME, EMAIL_ADDRESS, DOB) 
      VALUES (?, ?, ?, ?, ?)"; 

Trong bảng USER có một PRIMARY KEY (USER_ID) mà là một BIGINT AUTOINCREMENT (do đó tại sao bạn không nhìn thấy nó trong chuỗi SQL_CREATE.

Bây giờ, tôi điền số ? bằng cách sử dụng PreparedStatement.setXXXX(index, value). Tôi muốn trả lại ResultSet rs = PreparedStatement.getGeneratedKeys(). Làm thế nào tôi có thể đạt được điều này?

+2

Nhiều người hiểu sai và sử dụng PreparedStatement # executeUpdate (arg). Java doc nói 'Phương thức này với đối số không thể được gọi trên một PreparedStatement hoặc CallableStatement.' Nó có nghĩa là chúng ta phải sử dụng executeUpdate() mà không có đối số mặc dù phương thức' executeUpdate (arg) 'có thể được thừa kế trong lớp PreparedStatement nhưng chúng ta không có để sử dụng nó nếu không chúng ta sẽ nhận được SQLException. – AmitG

Trả lời

107

Bạn có thể sử dụng phương pháp prepareStatement dùng thêm int tham số

PreparedStatement ps = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS) 

Đối với một số trình điều khiển JDBC (ví dụ, Oracle), bạn phải liệt kê một cách rõ ràng các tên cột hoặc chỉ số của các phím tạo:

PreparedStatement ps = con.prepareStatement(sql, new String[]{"USER_ID"}) 
+0

Tôi đã chấp nhận câu trả lời của bạn vì bạn đã cho thấy nhiều cách hơn để đạt được kết quả tương tự. –

8

Hiện không có trình biên dịch của tôi, tôi sẽ trả lời bằng cách đặt câu hỏi:

Bạn đã thử cái này chưa? Nó có hoạt động không?

long key = -1L; 
PreparedStatement statement = connection.prepareStatement(); 
statement.executeUpdate(YOUR_SQL_HERE, PreparedStatement.RETURN_GENERATED_KEYS); 
ResultSet rs = statement.getGeneratedKeys(); 
if (rs != null && rs.next()) { 
    key = rs.getLong(1); 
} 

Tuyên bố từ chối trách nhiệm: Rõ ràng, tôi chưa biên soạn, nhưng bạn có ý tưởng.

PreparedStatement là một giao diện con của Statement, vì vậy tôi không thấy lý do tại sao điều này sẽ không hoạt động, trừ khi một số trình điều khiển JDBC lỗi.

+0

đó không phải là những gì tôi đang tìm kiếm Tôi biết rằng 'PreparedStatement' là một phân lớp của' Statement' .... xem bài viết cập nhật của tôi. –

52

Bạn có ý nghĩa như thế này?

long key = -1L; 

PreparedStatement preparedStatement = connection.prepareStatement(YOUR_SQL_HERE, PreparedStatement.RETURN_GENERATED_KEYS); 
preparedStatement.setXXX(index, VALUE); 
preparedStatement.executeUpdate(); 

ResultSet rs = preparedStatement.getGeneratedKeys(); 

if (rs.next()) { 
    key = rs.getLong(1); 
} 
+0

Bingo .... Tôi không thể nhìn thấy nó. Cảm ơn! –

+0

Làm thế nào các tập hợp khóa được tạo ra có thể là null? –

0
private void alarmEventInsert(DriveDetail driveDetail, String vehicleRegNo, int organizationId) { 

    final String ALARM_EVENT_INS_SQL = "INSERT INTO alarm_event (event_code,param1,param2,org_id,created_time) VALUES (?,?,?,?,?)"; 
    CachedConnection conn = JDatabaseManager.getConnection(); 
    PreparedStatement ps = null; 
    ResultSet generatedKeys = null; 
    try { 
     ps = conn.prepareStatement(ALARM_EVENT_INS_SQL, ps.RETURN_GENERATED_KEYS); 
     ps.setInt(1, driveDetail.getEventCode()); 
     ps.setString(2, vehicleRegNo); 
     ps.setString(3, null); 
     ps.setInt(4, organizationId); 
     ps.setString(5, driveDetail.getCreateTime()); 
     ps.execute(); 
     generatedKeys = ps.getGeneratedKeys(); 
     if (generatedKeys.next()) { 
      driveDetail.setStopDuration(generatedKeys.getInt(1)); 
     } 
    } catch (SQLException e) { 
     e.printStackTrace(); 
     logger.error("Error inserting into alarm_event : {}", e 
       .getMessage()); 
     logger.info(ps.toString()); 
    } finally { 
     if (ps != null) { 
      try { 

       if (ps != null) 
        ps.close(); 
      } catch (SQLException e) { 
       logger.error("Error closing prepared statements : {}", e 
         .getMessage()); 
      } 
     } 
    } 
    JDatabaseManager.freeConnection(conn); 
} 
+1

Bạn không nên giải phóng kết nối của bạn trong khối cuối cùng, không phải bên ngoài nó (bạn sẽ leek một kết nối nếu bạn nhận được một ngoại lệ thời gian chạy của bất kỳ loại)? – Jules

+0

@niraj - thay vì ps.RETURN_GENERATED_KEYS, chúng ta có thể viết Statement.RETURN_GENERATED_KEYS vì nó là biến tĩnh trong lớp java.sql.Statement. – AmitG

0
String query = "INSERT INTO ...."; 
PreparedStatement preparedStatement = connection.prepareStatement(query, PreparedStatement.RETURN_GENERATED_KEYS); 

preparedStatement.setXXX(1, VALUE); 
preparedStatement.setXXX(2, VALUE); 
.... 
preparedStatement.executeUpdate(); 

ResultSet rs = preparedStatement.getGeneratedKeys(); 
int key = rs.next() ? rs.getInt(1) : 0; 

if(key!=0){ 
    System.out.println("Generated key="+key); 
} 
+0

Nếu khóa được tạo thì khóa nếu không thì khóa = 0 nếu không được tạo –

Các vấn đề liên quan