2016-07-06 13 views
5

Trước khi đọc tài liệu, tôi đã dự kiến ​​phương pháp insertOrThrow() của phương thức SQLiteDatabase đã ném ngoại lệ nếu chèn không thành công.Android - Khi nào thì insertOrThrow() ném một ngoại lệ?

Tuy nhiên, documentation nói rằng insertOrThrow() phương pháp

trả về ID dãy hàng mới được chèn, hoặc -1 nếu có lỗi xảy ra

Vì vậy, nếu nó trả -1 khi một lỗi xảy ra, trong hoàn cảnh nào nó ném một ngoại lệ?

+0

Khi xảy ra lỗi, chẳng hạn như lỗi IO, tập dữ liệu sai, đóng dấu con trỏ, đặc quyền không writte writte cố gắng, vv Chủ yếu là nếu có lỗi xảy ra, -1 (không có hàng bị ảnh hưởng) thông tin được cung cấp – Bonatti

Trả lời

-1

Phương thức insertOrThrow() ném ngoại lệ và trả về -1. Bằng cách này bạn có thể kiểm tra xem truy vấn của bạn có thành công hay không. Nếu nó trả về -1 hành động của bạn không được hoàn thành và bạn cần phải tìm ra những gì đã xảy ra!

+1

Nó có thể 't return '-1' ** và ** ném một ngoại lệ cùng một lúc. Vì vậy, câu hỏi của tôi là khi nào nó trả về '-1' và khi nào nó ném một ngoại lệ. –

0

Bạn có thể tra cứu SQLiteDatabase source code để xem cách hoạt động. Có vẻ như nó sẽ ném một SQLiteDatabaseCorruptException nếu chuỗi SQL không hợp lệ, ngược lại trả về -1.

+0

Trường hợp ngoại lệ được ném từ mã C++. –

+0

Bạn có thể giải thích? Các liên kết trong bài viết của tôi cho thấy phương pháp anh ta hỏi về, mà ném một SQLiteDatabaseException trên một cuộc gọi executeInsert. – bradkratky

+0

Điều khoản 'throws' chỉ định những ngoại lệ mà hàm * có thể * ném. Không có câu lệnh 'throw' nào trong mã bạn đã liên kết tới. –

3

Sự hiểu biết của tôi là nó sẽ trả về -1 nếu tất cả mã có thể được thực hiện đúng và lỗi "EXPECTED" đã xảy ra. Tuy nhiên, không phải tất cả các lỗi/trường hợp ngoại lệ được xử lý và một số trường hợp ngoại lệ vẫn có thể được kích hoạt:

  • SQLiteDatabaseCorruptException
  • IllegalArgumentException
  • RuntimeException
  • Cơ sở dữ liệu được mở ra cho read-only
  • Đang cố gắng để chèn một nhân đôi khóa

HERE bạn có thể tìm thấy việc triển khai insert()insertOrThrow().

Bạn có thể thấy cả hai phương pháp đều giống nhau. Tuy nhiên, insert() xử lý SQLException giây cho bạn. insertOrThrow() không xử lý bất kỳ ngoại lệ nào và bạn nên tự làm điều đó.

public long insert(String table, String nullColumnHack, ContentValues values) { 
    try { 
     return insertWithOnConflict(table, nullColumnHack, values, CONFLICT_NONE); 
    } catch (SQLException e) { 
     Log.e(TAG, "Error inserting " + values, e); 
     return -1; 
    } 
} 

public long insertOrThrow(String table, String nullColumnHack, ContentValues values) 
     throws SQLException { 
    return insertWithOnConflict(table, nullColumnHack, values, CONFLICT_NONE); 
} 

Cả hai phương pháp gọi insertWithOnConflict() mà thực hiện là HERE:

public long insertWithOnConflict(String table, String nullColumnHack, 
     ContentValues initialValues, int conflictAlgorithm) { 
    acquireReference(); 
    try { 
     // CODE 
     try { 
      // ONLY HERE I return some value.... Otherwise, I'll raise an exception 
      return statement.executeInsert(); 
     } finally { 
      statement.close(); 
     } 
    } finally { 
     releaseReference(); 
    } 
} 

Trong việc thực hiện, bạn sẽ thấy rằng nó sẽ trả về "-1" chỉ khi statement.executeInsert(); lợi nhuận một cái gì đó (và có vẻ như rằng "-1 "đến từ đây):

.../khung/cơ sở/lõi/JNI/android_database_SQLiteConnection.cpp

static jlong nativeExecuteForLastInsertedRowId(JNIEnv* env, jclass clazz, 
     jlong connectionPtr, jlong statementPtr) { 
    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr); 
    sqlite3_stmt* statement = reinterpret_cast<sqlite3_stmt*>(statementPtr); 

    int err = executeNonQuery(env, connection, statement); 
    return err == SQLITE_DONE && sqlite3_changes(connection->db) > 0 
      ? sqlite3_last_insert_rowid(connection->db) : -1; 
} 

Nếu có bất kỳ lỗi/ngoại lệ nào khác xảy ra ở giữa, nó sẽ ném một ngoại lệ.

Nếu bạn làm theo các phương pháp được gọi, bạn có thể thấy rằng các lỗi khác không được xử lý. Ngoài ra, bạn sẽ nhận thấy rằng SQLite sẽ thực tế được thực hiện bởi một nhiệm vụ C (chứ không phải java). Vì vậy, một số lỗi không mong đợi vẫn có thể xảy ra.

+0

Điều này vẫn không trả lời khi chính xác '-1' được trả về. 'executeNonQuery' luôn trả về' SQLITE_DONE'. –

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