2013-02-22 105 views
0

假設您不想爲以下表myTable回收rowid。在Android/SQLite中獲取未使用的rowid的有效方法?

對於定義:

CREATE TABLE myTable 
(
    id INTEGER PRIMARY KEY AUTOINCREMENT , 
    <Other columns> 
) 

然後你想獲得下一個未使用的rowid在安卓/ SQLite的環境。

你將如何有效地做到這一點?

也許我們需要反對 android.database.sqlite.SQLiteDatabase 也許(?)對象 android.database.sqlite.SQLiteStatement

,但什麼是最有效的方式做這個任務?

注意: 我不想創建行到myTable中。 但是,如果這是完成這項工作的最佳方式,當然你可以創建行並刪除它 。

回答

0

正如您發現的那樣,創建一行並刪除它是一種有效的方法。另一種方式是運行一個

SELECT id FROM myTable ORDER BY id DESC 

然後查看返回的第一行的id並將其加1。雖然小心併發。如果在檢查未使用的行之後立即插入某些內容,則可能會出現意外的行爲。

編輯:查看CL。的回答。這更實用。另外,您可以手動更新該表的序列號,以確保您的行不會被使用。

0

我永遠無法理解爲什麼會有人需要做到這一點,但它可以做到:

The SQLite documentation提到,AUTO_INCREMENT值存儲在其中當您使用auto_increments在數據庫中自動創建一個sqlite_sequence表。

This S.O. answer解釋了查詢sqlite_sequence表以查找當前最大ID的一種方法,然後您可以將1添加到該表中,並且99.9%的時間將成爲下一個發佈的ID。

+0

該表中包含最後使用的ID。 然後我必須更新一個,然後選擇該表 這個簡單的重要任務? – heivik 2013-02-22 16:46:49

0

所以答案是這樣的:

db.execSQL("UPDATE sqlite_sequence set seq=seq+1 WHERE name='myTable'"); 

SQLiteStatement st = db.compileStatement("SELECT seq from sqlite_sequence WHERE name='myTable'"); 
long v = st.simpleQueryForLong(); 
st.close(); 

現在v是未使用的ROWID哪些其他人不會得到。 也許這些陳述必須在同一交易中。

對於簡單而相當常見的任務並不那麼簡單?

+0

簡單且相當常見的任務就是插入新記錄。你爲什麼不想這樣做? – 2013-02-22 18:04:59

+0

再一次: 我不想插入記錄在同一時刻 當我需要身份證,但我必須確定該ID是保留給我。 因此插入不起作用。插入+刪除工程,但不是很好。 – heivik 2013-02-22 19:57:41

+0

來自SQLite手冊的警告: 「對此表進行修改可能會干擾AUTOINCREMENT密鑰生成算法。請確保在進行此類更改之前知道您正在做什麼。」 你也應該記住AUTOINCREMENT行不會總是成爲下一個數字。某些情況可能會導致自動增量值提供一個數字,該數字是a)比當前值大1以上或b)之前刪除的另一個行ID。 我會插入一個空行來保留一個ID,然後用UPDATE填充缺失的數據。 – 2013-02-24 23:16:14

0

在你使用的SQLiteOpenHelper裏面,開始一個事務。插入一些數據,然後回滾。

這樣,您將能夠獲得下一行的ID,像這樣:

public long nextId() { 
    long rowId = -1; 

    SQLiteDatabase db = getWritableDatabase(); 
    db.beginTransaction(); 
    try { 
     ContentValues values = new ContentValues(); 
     // fill values ... 

     // insert a valid row into your table 
     rowId = db.insert(TABLE_NAME, null, values); 

     // NOTE: we don't call db.setTransactionSuccessful() 
     // so as to rollback and cancel the last changes 
    } finally { 
     db.endTransaction(); 
    } 
    return rowId; 
} 
相關問題