[英]Android column '_id' does not exist?
我在記事本示例中遇到了一些問題。 這是 NotepadCodeLab/Notepadv1Solution 中的代碼:
String[] from = new String[] { NotesDbAdapter.KEY_TITLE };
int[] to = new int[] { R.id.text1 };
SimpleCursorAdapter notes = new SimpleCursorAdapter(this,
R.layout.notes_row, c, from, to);
這段代碼似乎工作正常。 但為了清楚起見,我運行了ADB實用程序並運行了 SQLite 3。我按如下方式檢查了架構:
sqlite> .schema
CREATE TABLE android_metadata (locale TEXT);
CREATE TABLE notes (_id integer primary key autoincrement, title text
not null, body text not null);
我覺得一切都很好。
現在到我的應用程序,據我所知,它與一些小的更改基本相同。 我已經簡化並簡化了我的代碼,但問題仍然存在。
String[] from = new String[] { "x" };
int[] to = new int[] { R.id.x };
SimpleCursorAdapter adapter = null;
try
{
adapter = new SimpleCursorAdapter(this, R.layout.circle_row, cursor, from, to);
}
catch (RuntimeException e)
{
Log.e("Circle", e.toString(), e);
}
當我運行我的應用程序時,我從我的Log.e()
語句中得到一個 RuntimeException 和以下打印在 LogCat 中:
LogCat 消息:
java.lang.IllegalArgumentException: 列“_id”不存在
所以,回到 SQLite 3 看看我的架構有什么不同:
sqlite> .schema CREATE TABLE android_metadata (locale TEXT); CREATE TABLE circles (_id integer 主鍵自增,序列整數,radius real, x real, y real);
我不明白我是如何錯過“_id”的。
我做錯了什么?
我的應用程序和記事本示例之間的不同之處在於,我首先使用 Eclipse 向導從頭開始創建我的應用程序,而示例應用程序已經放在一起。 我是否需要對新應用程序進行某種環境更改才能使用 SQLite 數據庫?
我看到, CursorAdapter的文檔指出:
Cursor 必須包含名為
_id
的列,否則此類將不起作用。
SimpleCursorAdapter
是一個派生類,因此似乎此語句適用。 但是,該聲明在技術上是錯誤的,並且對新手有些誤導。 游標的結果集必須包含_id
,而不是游標本身。
我相信這對 DBA 來說很清楚,因為他們很清楚那種速記文檔,但是對於那些新手來說,聲明中的不完整會導致混淆。 游標就像迭代器或指針,它們只包含一種用於遍歷數據的機制,它們本身不包含列。
Loaders 文檔包含一個示例,其中可以看到_id
包含在投影參數中。
static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] {
Contacts._ID,
Contacts.DISPLAY_NAME,
Contacts.CONTACT_STATUS,
Contacts.CONTACT_PRESENCE,
Contacts.PHOTO_ID,
Contacts.LOOKUP_KEY,
};
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// ...
return new CursorLoader(getActivity(), baseUri,
CONTACTS_SUMMARY_PROJECTION, select, null,
Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
}
這已經得到了回答,我想在這里讓它更全面。
SimpleCursorAdapter 要求 Cursor 的結果集必須包含一個准確命名為“_id”的列。 如果您沒有在表中定義“_id”列,請不要急於更改架構。 SQLite 自動為每個表添加了一個名為“rowid”的隱藏列。 您需要做的就是明確選擇 rowid 並將其別名為“_id”Ex。
SQLiteDatabase db = mHelper.getReadableDatabase();
Cursor cur = db.rawQuery( "select rowid _id,* from your_table", null);
Tim Wu 的代碼真的有效......
如果您使用的是 db.query,那么它會是這樣的...
db.query(TABLE_USER, new String[] {
"rowid _id",
FIELD_USERNAME,
},
FIELD_USERNAME + "=" + name,
null,
null,
null,
null);
是的,我還更改了 SELECT 字符串查詢以解決此問題。
String query = "SELECT t.*,t.id as _id FROM table t ";
解決這個錯誤的問題是我沒有在我的數據庫查詢中包含 _id 列。 添加它解決了我的問題。
這可能不再相關,但我今天遇到了同樣的問題。 原來列名是區分大小寫的。 我有一個 _ID 列,但 Android 需要一個 _id 列。
如果您閱讀了 sqlite 上的文檔,則創建任何類型為 INTEGER PRIMARY KEY 的列都會在內部為 ROWID 設置別名,因此在每個 SELECT 中添加別名的麻煩是不值得的,這與任何可能利用諸如定義表的列的枚舉。
http://www.sqlite.org/autoinc.html
使用它作為 ROWID 而不是 AUTOINCREMENT 選項也更直接,因為 _ID 可能會偏離 ROWID。 通過將 _ID 綁定到 ROWID 意味着從 insert/insertOrThrow 返回主鍵; 如果您正在編寫 ContentProvider,您可以在返回的 Uri 中使用此鍵。
處理表中缺少 _id 列的另一種方法是編寫 CursorWrapper 的子類,如果需要,它會添加一個 _id 列。
這具有不需要對表或查詢進行任何更改的優點。
我寫過這樣一個類,如果有興趣可以在https://github.com/cmgharris/WithIdCursorWrapper找到
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.