2012-07-04 22 views
7

Tôi có một bảng địa chỉ đơn giản với tạo sau đây tuyên bố:Android sqllite VỀ XUNG ĐỘT bỏ qua là bỏ qua trong ICS

"CREATE TABLE " + ADDRESSES_TABLE + " (" + 
       KEY_ADDRESS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + 
       KEY_ADDRESS_COUNTRY + " TEXT, " + 
       KEY_ADDRESS_CITY + " TEXT, " + 
       KEY_ADDRESS_STREET + " TEXT, " + 
       KEY_ADDRESS_HOUSE + " TEXT, " + 
       KEY_ADDRESS_POSTAL_CODE + " TEXT," + 
       "UNIQUE("+KEY_ADDRESS_COUNTRY+","+KEY_ADDRESS_CITY+","+KEY_ADDRESS_STREET+","+KEY_ADDRESS_HOUSE+","+KEY_ADDRESS_POSTAL_CODE +") ON CONFLICT IGNORE)" 

Khi tôi thêm các bản ghi trùng lặp, chèn() Metod lợi nhuận -1 và không phải là id của hàng hiện tại.

Sự cố chỉ có thể sao chép được trên 4.0+. Phương thức hoạt động như mong đợi trên 2.2 và 2.3.3.

Có ai phải đối mặt với cùng một vấn đề không?

+0

Bạn đang sử dụng 'insert' hoặc' insertWithOnConflict'? – Barak

+0

Tôi đã thử cả hai, nhưng tôi nghĩ rằng insertWithOnConflict không có ý nghĩa nếu tôi đã chỉ định ON CONFLICT IGNORE trong TABLE CREATE. – Zzokk

Trả lời

9

Thật không may, tài liệu Android bị sai. (Và do đó mã của bạn không thực sự hoạt động như mong đợi trên các phiên bản trước của Android, ví dụ: 2.2 và 2.3.)

Trong 2.2 và 2.3, insertWithOnConflict() sẽ trả về giá trị của hàm API SQLite sqlite3_last_insert_rowid(). chèn không thành công (ví dụ, khi độ phân giải ON CONFLICT, như IGNORE, được áp dụng) không ảnh hưởng đến giá trị trả về. Do đó, nếu không có chèn trước cho kết nối được thực hiện và chèn một bản sao, insertWithOnConflict() sẽ trả về 0. Nếu chèn trước đã thêm hàng vào bảng bất kỳ, phương thức sẽ trả về id hàng rằng chèn --- của Tất nhiên điều này là không chính xác.

Trong 4.0, insertWithOnConflict() sẽ trả về giá trị so với cùng chức năng API SQLite C, ngoại trừ trở về -1 thay vì 0.

Sự thay đổi này là lý do tại sao bạn đang quan sát các lỗi. Nhưng nếu bạn kiểm tra kết quả chặt chẽ trong 2.2 và 2.3, bạn sẽ thấy rằng các id hàng trả lại khi mệnh đề OR IGNORE được thực hiện không thực sự là id hàng chính xác (ngoại trừ tình cờ).

+0

nếu điều này thực sự là hành vi đúng, bạn nên [gửi nó dưới dạng lỗi] (http://source.android.com/source/report-bugs.html) ... không thể làm tổn thương: D –

+1

Nó ở đó dưới dạng ấn bản 13045: https://code.google.com/p/android/issues/detail?id=13045 –

+1

Cảm ơn bạn đã giải thích rõ. Tôi thực sự dựa vào phương pháp này. Vì vậy, cách giải quyết tốt nhất là: try { insertOrThrow (/ * Tất cả các params yêu cầu * /) } catch (SQLException e) {// Chọn bản ghi cần thiết và nhận được khóa chính từ nó } Không phải là nó quá nặng đối với DB về thời gian? – Zzokk