簡體   English   中英

sqlite 數據庫有時會以錯誤的順序插入數據

[英]sqlite database inserts data in the wrong order sometimes

我正在使用 android 工作室,我需要將一些數據插入數據庫。 有時,它可以工作,但有時,我會收到此錯誤。 我真的無法弄清楚它工作的時間和不工作的時間之間的區別。

2019-11-09 11:38:34.912 4369-4369/com.example.android.fresh 
D/DatabaseHelper: addData: Adding John Smith to people_table
2019-11-09 11:38:34.913 4369-4369/com.example.android.fresh E/SQLiteLog: 
(20) statement aborts at 5: [INSERT INTO 
people_table(name,amount,contact_no) VALUES (?,?,?)] datatype mismatch
2019-11-09 11:38:34.916 4369-4369/com.example.android.fresh 
E/SQLiteDatabase: Error inserting name=John Smith amount=255.0 contact_no= 1234567890 from {P:4369;U:10178}
android.database.sqlite.SQLiteDatatypeMismatchException: datatype mismatch (code 20 SQLITE_MISMATCH)
    at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
    at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:796)
    at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
    at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
    at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1613)
    at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1482)
    at com.example.android.fresh.DatabaseHelper.addData(DatabaseHelper.java:51)
    at com.example.android.fresh.createPerson.AddData(createPerson.java:94)
    at com.example.android.fresh.createPerson$1.onClick(createPerson.java:58)
    at android.view.View.performClick(View.java:6669)
    at android.view.View.performClickInternal(View.java:6638)
    at android.view.View.access$3100(View.java:789)
    at android.view.View$PerformClick.run(View.java:26145)
    at android.os.Handler.handleCallback(Handler.java:873)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:193)
    at android.app.ActivityThread.main(ActivityThread.java:6898)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:537)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

我的數據庫助手 class 中的相關代碼如下:

private static final String COL1 = "contact_no";
private static final String COL2 = "name";
private static final String COL3 = "amount";

@Override
public void onCreate(SQLiteDatabase db) {
String createTable = "CREATE TABLE " + TABLE_NAME + " (ID INTEGER PRIMARY KEY AUTOINCREMENT,"
            + COL1 + " TEXT NOT NULL," +
            COL2 + " TEXT NOT NULL,"
            + COL3 + " REAL)" ;
    db.execSQL(createTable);

public boolean addData(String contactNo, String contactName, double amount) {
    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues contentValues = new ContentValues();
    contentValues.put(COL1, contactNo);
    contentValues.put(COL2, contactName);
    contentValues.put(COL3, amount);

    Log.d(TAG, "addData: Adding " + contactName + " to " + TABLE_NAME);

    long result = db.insert(TABLE_NAME, null, contentValues);

    if (result == -1) {
        return false;
    } else {
        return true;
    }
}

這是 createPerson class 中的代碼:

public void AddData(String contactNo, String contactName, double amount) {
    boolean insertData = mDatabaseHelper.addData(contactNo, contactName, amount);

    if (insertData) {
        check =1;
        toastMessage("Contact Inserted");
    } else {
        toastMessage("Something went wrong");
    }
}

這是方法調用語句:

 AddData(contactNumber, contactName, amount);

這些中的每一個都按contactNumber、contactName和amount的順序排列,但是我得到的sqlite錯誤是按contactName、amount和contactNumber的順序插入它。 我真的無法理解這是怎么回事。

只有一種情況會發生數據類型不匹配,因為 SQLite 能夠在任何類型的列中存儲任何類型的數據(有 1 個例外,因此是原因/問題)。

  • 您希望閱讀SQLite 版本 3中的數據類型,因為這解釋了類型以及與典型數據庫相比它的靈活性。 它還解釋了 rowid 的別名和 AUTOINCREMENT。

例外情況是作為 rowid 列的別名的列。 rowid 列的別名是通過使用 INTEGER PRIMARY KEY 定義的(特別是 INTEGER 不是 INT 或不會導致派生類型為 INTEGER 的任何其他值)。

  • 請注意,可以將 AUTOINCREMENT 添加到(並且僅添加到)定義中,盡管這樣做效率低下,並且很少需要。

rowid 及其別名必須包含 integer 值(最多 64 位有符號)。

因此,您以某種方式嘗試將非整數值插入到 rowid 的別名中,如果使用所示的 SQL 來創建表,則情況並非如此。

因此,SQL 尚未成功運行並創建表,但很可能原因是存在使用不同 SQL 創建的先前表。

簡單地更改創建 SQL 不會導致表被更改 那是因為數據庫在運行之間持續存在(停留在那里)。 因此, onCreate方法只會在數據庫的生命周期內自動運行一次。

如果您更改架構(創建 SQL),那么您必須找到某種方法來運行 SQL(這將涉及刪除表)。 開發應用程序時最簡單的方法是

  1. 刪除應用程序的數據,
  2. 卸載應用程序或
  3. 增加版本號
    1. 僅當 onUpgrade 刪除表以便可以重新創建它們並調用更改的 SQL(通常通過調用 onCreate)時,后一個選項才有效。

執行上述任一操作后,應重新運行應用程序。

  • 請注意,上述選項都會導致當前數據丟失。 如果需要保留當前數據,則該過程會更加復雜,並且可能涉及用於重命名表的 ALTER 語句和將數據從原始表復制 (INSERT) 到新表的語句。

@MikeT 已經詳細回答了這個問題,但是我想知道:為什么不遵循架構設計模式並實現 Android Room? 使用 Room,您不必擔心這種“低級”錯誤。 它會告訴你哪里出了問題,這就是它的設計目的。 提示:讓 Room 為您完成插入並對持久數據感到滿意

聯系電話是否不是作為字符串存儲的,而是作為數字數據類型存儲的? 您的日志語句在聯系電話的開頭顯示一個空格。

contact_no= 1234567890

我想知道 sqlite 是否因此無法將其轉換為 integer。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM