Android 列“_id”不存在?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3359414/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android column '_id' does not exist?
提问by Andrew
I'm having trouble with something that works in the Notepad example. Here's the code from the NotepadCodeLab/Notepadv1Solution:
我在记事本示例中遇到了一些问题。这是 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);
This code seems to work fine. But just to be clear, I ran the ADButility and run SQLite 3. I inspected the schema as follows:
这段代码似乎工作正常。但为了清楚起见,我运行了ADB实用程序并运行了 SQLite 3。我按如下方式检查了架构:
sqlite> .schema
sqlite> .schema
CREATE TABLE android_metadata (locale TEXT);
CREATE TABLE notes (_id integer primary key autoincrement, title text
not null, body text not null);
All seems good to me.
我觉得一切都很好。
Now on to my application, which, as far as I can see, is basically the same with a few minor changes. I've simplified and simplified my code, but the problem persists.
现在到我的应用程序,据我所知,它与一些小的更改基本相同。我已经简化并简化了我的代码,但问题仍然存在。
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);
}
When I run my application, I get a RuntimeException and the following prints
in LogCat from my Log.e()
statement:
当我运行我的应用程序时,我从我的Log.e()
语句中得到一个 RuntimeException 和 LogCat 中的以下打印:
LogCat Message:
LogCat 消息:
java.lang.IllegalArgumentException: column '_id' does not exist
java.lang.IllegalArgumentException: 列“_id”不存在
So, back to SQLite 3 to see what's different about my schema:
所以,回到 SQLite 3 看看我的架构有什么不同:
sqlite> .schema CREATE TABLE android_metadata (locale TEXT); CREATE TABLE circles (_id integer primary key autoincrement, sequence integer, radius real, x real, y real);
sqlite> .schema CREATE TABLE android_metadata (locale TEXT); CREATE TABLE circles (_id integer 主键自增,序列整数,radius real, x real, y real);
I don't see how I'm missing the '_id'.
我不明白我是如何错过“_id”的。
What have I done wrong?
我做错了什么?
One thing that's different between my application and the Notepad example is that I started by creating my application from scratch using the Eclipse wizard while the sample application comes already put together. Is there some sort of environmental change I need to make for a new application to use a SQLite database?
我的应用程序和记事本示例之间的不同之处在于,我首先使用 Eclipse 向导从头开始创建我的应用程序,而示例应用程序已经放在一起。我是否需要对新应用程序进行某种环境更改才能使用 SQLite 数据库?
回答by user405821
I see, the documentation for CursorAdapterstates:
我看到,CursorAdapter的文档指出:
The Cursor must include a column named
_id
or this class will not work.
Cursor 必须包含一个名为的列,
_id
否则此类将不起作用。
The SimpleCursorAdapter
is a derived class, so it appears this statement applies. However, the statement is technically wrong and somewhat misleading to a newbie. The result setfor the cursor must contain _id
, not the cursor itself.
I'm sure this is clear to a DBA because that sort of shorthand documentation is clear to them, but for those newbies, being incomplete in the statement causes confusion. Cursors are like iterators or pointers, they contain nothing but a mechanism for transversing the data, they contain no columns themselves.
该SimpleCursorAdapter
是一个派生类,所以会出现这种情况适用。但是,该声明在技术上是错误的,并且对新手有些误导。游标的结果集必须包含_id
,而不是游标本身。
我相信这对 DBA 来说很清楚,因为他们很清楚那种速记文档,但对于那些新手来说,声明中的不完整会导致混淆。游标就像迭代器或指针,它们只包含一种用于遍历数据的机制,它们本身不包含列。
The Loaders documentationcontains an example where it can be seen that the _id
is included in the projectionparameter.
该装载机文档包含在那里可以使可见的例子_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");
}
回答by Tim Wu
This has been answeredand I would like to make it more comprehensive here.
这已经得到了回答,我想在这里让它更全面。
SimpleCursorAdapter requires that the Cursor's result set must include a column named exactly "_id". Don't haste to change schema if you didn't define the "_id" column in your table. SQLite automatically added an hidden column called "rowid" for every table. All you need to do is that just select rowid explicitly and alias it as '_id' Ex.
SimpleCursorAdapter 要求 Cursor 的结果集必须包含一个准确命名为“_id”的列。如果您没有在表中定义“_id”列,请不要急于更改架构。SQLite 自动为每个表添加了一个名为“rowid”的隐藏列。您需要做的就是明确选择 rowid 并将其别名为“_id”Ex。
SQLiteDatabase db = mHelper.getReadableDatabase();
Cursor cur = db.rawQuery( "select rowid _id,* from your_table", null);
回答by Deepzz
Tim Wu's code really works...
Tim Wu 的代码真的有效......
If you are using db.query, then it would be like this...
如果您使用的是 db.query,那么它会是这样的...
db.query(TABLE_USER, new String[] {
"rowid _id",
FIELD_USERNAME,
},
FIELD_USERNAME + "=" + name,
null,
null,
null,
null);
回答by Felipe FMMobile
Yes , I also change the SELECT string query to fix this issue.
是的,我还更改了 SELECT 字符串查询以解决此问题。
String query = "SELECT t.*,t.id as _id FROM table t ";
回答by RoadXY
What solved my issue with this error was that I had not included the _id column in my DB query. Adding that solved my problem.
解决这个错误的问题是我没有在我的数据库查询中包含 _id 列。添加它解决了我的问题。
回答by zmbq
This probably isn't relevant anymore, but I just hit the same problem today. Turns out column names are case sensitive. I had an _ID column, but Android expects an _id column.
这可能不再相关,但我今天遇到了同样的问题。原来列名是区分大小写的。我有一个 _ID 列,但 Android 需要一个 _id 列。
回答by Eric Woodruff
If you read the docs on sqlite, creating any column of type INTEGER PRIMARY KEY will internally alias the ROWID, so it isn't worth the trouble of adding an alias in every SELECT, deviating from any common utilities that might take advantage of something like an enum of columns defining the table.
如果您阅读了 sqlite 上的文档,则创建任何类型为 INTEGER PRIMARY KEY 的列都会在内部为 ROWID 设置别名,因此在每个 SELECT 中添加别名的麻烦是不值得的,这与任何可能利用诸如定义表的列的枚举。
http://www.sqlite.org/autoinc.html
http://www.sqlite.org/autoinc.html
It is also more straightforward to use this as the ROWID instead of the AUTOINCREMENT option which can cause _ID can deviate from the ROWID. By tying _ID to ROWID it means that the primary key is returned from insert/insertOrThrow; if you are writing a ContentProvider you can use this key in the returned Uri.
使用它作为 ROWID 而不是 AUTOINCREMENT 选项也更直接,这会导致 _ID 可能偏离 ROWID。通过将 _ID 绑定到 ROWID 意味着从 insert/insertOrThrow 返回主键;如果您正在编写 ContentProvider,您可以在返回的 Uri 中使用此键。
回答by cmgharris
Another way of dealing with the lack of an _id column in the table is to write a subclass of CursorWrapper which adds an _id column if necessary.
处理表中缺少 _id 列的另一种方法是编写 CursorWrapper 的子类,如果需要,它会添加一个 _id 列。
This has the advantage of not requiring any changes to tables or queries.
这具有不需要对表或查询进行任何更改的优点。
I have written such a class, and if it's of any interest it can be found at https://github.com/cmgharris/WithIdCursorWrapper
我写过这样一个类,如果有兴趣可以在https://github.com/cmgharris/WithIdCursorWrapper找到