Android专栏'_id'不存在?

And*_*rew 72 sqlite android listview

我在使用记事本示例中的某些功能时遇到了问题.这是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);
Run Code Online (Sandbox Code Playgroud)

这段代码似乎工作正常.但为了清楚起见,我运行了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);
Run Code Online (Sandbox Code Playgroud)

一切对我来说都很好.


现在我的应用程序,据我所知,基本相同,只有一些小的改动.我简化并简化了我的代码,但问题仍然存在.

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);
}
Run Code Online (Sandbox Code Playgroud)

当我运行我的应用程序时,我得到一个RuntimeException并在我的Log.e()语句中在LogCat中打印以下内容:

LogCat消息:

java.lang.IllegalArgumentException:列'_id'不存在

那么,回到SQLite 3来看看我的架构有什么不同:

sqlite> .schema CREATE TABLE android_metadata(locale TEXT); CREATE TABLE圆圈(_id整数主键自动增量,序列整数,半径实数,x实数,y实数);

我不知道我是如何错过'_id'的.

我做错了什么?

我的应用程序和Notepad示例之间的一个不同之处在于,我首先使用Eclipse向导从头创建应用程序,同时示例应用程序已经放在一起.我是否需要为新应用程序使用SQLite数据库进行某种环境变更?

use*_*821 153

我明白了,CursorAdapter文档说明:

Cursor必须包含一个名为的列,_id否则此类将不起作用.

SimpleCursorAdapter是一个派生类,所以看来这个陈述适用.然而,该声明在技术上是错误的,并且对新手有些误导.游标的结果集必须包含_id,而不是游标本身.
我确信这对DBA来说是清楚的,因为那种速记文档对他们来说是清楚的,但对于那些新手来说,在声明中不完整会引起混淆.游标就像迭代器或指针一样,它们只包含一个用于遍历数据的机制,它们本身不包含任何列.

装载机文档包含在那里可以使可见的例子_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");
}
Run Code Online (Sandbox Code Playgroud)

  • 我建议将文档中的语句写成"Cursor的结果集必须包含一个名为"_id"的列.如果不这样做,将产生RuntimeException." 这样可以减少混淆和纠正. (15认同)
  • @ user405821 - 谢谢你 - 这个家伙并没有把你的答案标记为正确 - 但这是对Android部分文档记录不足的一个很好的补充.+1 (6认同)

Tim*_* Wu 104

这已得到回答,我想在这里更全面.

SimpleCursorAdapter要求Cursor的结果集必须包含一个名为"_id"的列.如果未在表中定义"_id"列,请不要急于更改架构.SQLite为每个表自动添加了一个名为"rowid"的隐藏列.您需要做的就是明确选择rowid并将其别名为'_id'Ex.

SQLiteDatabase db = mHelper.getReadableDatabase();      
Cursor cur =  db.rawQuery( "select rowid _id,* from your_table", null);
Run Code Online (Sandbox Code Playgroud)

  • 或者选择id作为_id (9认同)

Dee*_*pzz 20

Tim Wu的代码确实有用......

如果您正在使用db.query,那么它就像这样......

db.query(TABLE_USER, new String[] { 
                "rowid _id",
                FIELD_USERNAME,
                }, 
                FIELD_USERNAME + "=" + name, 
                null, 
                null, 
                null, 
                null);
Run Code Online (Sandbox Code Playgroud)


Fel*_*ile 8

是的,我还更改了SELECT字符串查询以解决此问题.

String query = "SELECT t.*,t.id as _id FROM table t "; 
Run Code Online (Sandbox Code Playgroud)


小智 7

解决了我的错误问题是我没有在数据库查询中包含_id列.添加它解决了我的问题.


zmb*_*mbq 6

这可能不再相关,但我今天遇到了同样的问题.结果列名称区分大小写.我有一个_ID列,但Android需要一个_id列.