簡體   English   中英

Android 列“_id”不存在?

[英]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.

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