2012-04-03 51 views
5

Tôi có một câu hỏi như sau:Không thể tìm thấy một chìa khóa được tạo ra trong Java sử dụng getGeneratedKeys PreparedStatement của()

String SQL = "insert into table (id, name) values (sequence.nextval, ?)"; 

sau đó tôi thực hiện một PreparedStatement như thế này:

//initiate connection, statement etc 
pStatement = connection.prepareStatement(SQL, Statement.RETURN_GENERATED_KEYS); 
pStatement.setString(1,'blabla'); 

pStatement.executeUpdate(); 
ResultSet rs = pStatement.getGeneratedKeys(); 

while (rs.next()){ 
    //debugging here to see what rs has 
} 

Khi thực hiện và gỡ lỗi tại rằng điểm gỡ lỗi, tôi thấy ResultSet của tôi chỉ có một khóa, một chuỗi - không giống như id mà tôi mong đợi. Khi kiểm tra cơ sở dữ liệu tất cả mọi thứ hoạt động tốt, id của được chèn vào và tất cả mọi thứ. Có điều gì đó về getGeneratedKeys(); gây nhầm lẫn cho tôi.

Tôi đang làm gì sai?

Cảm ơn trước

+2

bạn không sử dụng 'chìa khóa tạo ra', bạn chỉ cần sử dụng một máy phát điện trong INSERT của bạn tuyên bố. 'getGeneratedKeys()' được sử dụng để trả về các khóa do DB tạo ra như một phần của INSERT (bởi một cột nhận dạng hoặc thông qua một trigger). –

Trả lời

8

Tôi hy vọng rằng "khóa" bạn đang quay lại trông giống như một chuỗi là ROWID - đó là khóa duy nhất mà cơ sở dữ liệu trực tiếp tạo. Bạn sẽ có thể thay đổi điều đó để lấy lại cột id (điều này có thể yêu cầu một phiên bản vừa phải của trình điều khiển JDBC).

//initiate connection, statement etc 
String generatedColumns[] = {"ID"}; 
pStatement = connection.prepareStatement(SQL, generatedColumns); 
pStatement.setString(1,'blabla'); 

pStatement.executeUpdate(); 
ResultSet rs = pStatement.getGeneratedKeys(); 

while (rs.next()){ 
    //debugging here to see what rs has 
} 

Bạn cũng có thể thay đổi truy vấn của bạn để thêm một cách rõ ràng RETURNING khoản

String SQL = "insert into table (id, name) " + 
      " values (sequence.nextval, ?) " + 
      " returning id into ?"; 
+0

Cảm ơn bạn. Tôi đã chọn tùy chọn đầu tiên của bạn để bao gồm các cột được tạo. Thật vậy, ResultSet của tôi đầu tiên đã cho tôi một số dòng tôi không hiểu nhưng bây giờ tôi vượt qua chuỗi [] {"id"} trả về id mới được tạo ra. – arnehehe

1

Nếu điều này không hoạt động, sự cố có thể xảy ra với chuỗi.nextval. Dường như nếu bạn đang sử dụng điều đó, bạn không tự động phát huy phím

1

Tôi chắc chắn rằng getGeneratedKeys sẽ không trả lại giá trị của khóa đã được khởi tạo với giá trị tiếp theo của chuỗi. Thật vậy, trong trường hợp này, cơ sở dữ liệu không tự tạo khóa (giống như với cột tăng tự động).

Nếu bạn muốn biết chìa khóa tạo ra, sau đó thực hiện một truy vấn đầu tiên:

select sequence.nextval from dual 

và sau đó sử dụng kết quả của truy vấn đầu tiên này để thực thi tuyên bố chuẩn bị của bạn:

insert into table (id, name) values (?, ?) 
1

Tôi nghĩ này:

pStatement.setString('blabla'); 

phải là:

pStatement.setString(1, 'blabla'); 

Hy vọng điều đó sẽ hữu ích.

+0

Xin lỗi - bạn đã đúng. Đây là lỗi của tôi vì không sao chép dán mã của tôi ở đây nhưng cố gắng nhập ví dụ bằng các thuật ngữ tổng quát hơn để làm cho mã dễ đọc hơn. Tuy nhiên, trong mã của tôi, tôi đã thực hiện nó một cách chính xác. Vì vậy, trong khi bạn đang chính xác này không phải là vấn đề tôi đang đấu tranh với. Tôi đã chỉnh sửa bài đăng của mình. – arnehehe

+0

@arnehehe bạn nói đúng, bạn có thể biên dịch mã của bạn để đó không phải là lỗi. Lỗi của tôi. –

0

Mã của bạn có một lỗi: Vì bạn đang sử dụng PreparedStatement, bạn nên sử dụng riêng RETURN_GENERATED_KEYS liên tục của nó:

pStatement = connection.prepareStatement(SQL, PreparedStatement.RETURN_GENERATED_KEYS); 

Chức năng getGeneratedKeys() sẽ được thực hiện mà không có sự cố và bạn sẽ có thể nhận các khóa được tạo trong biến số ResultSet.

Bằng cách này, bạn không cần phải chỉ định bất kỳ tên nào cho hàng của bạn (như giải pháp của Justin gợi ý, điều này khá tốt).Bạn chỉ cần ghi rõ tên hàng của bạn nếu bạn truy cập các phím lấy ra sử dụng:

id = rs.getInt("id_row_name"); 

thay vì:

id = rs.getInt(column_number); //One column for each key retrieved. 
Các vấn đề liên quan