Android抛出SQLiteException: no such column _id,但未使用该列的问题
解决android.database.sqlite.SQLiteException: no such column _id异常
我太懂这种明明没碰过某个列却报错的困惑了!其实这个问题的根源不在你写的代码里,而是Android的CursorAdapter(以及它的子类比如SimpleCursorAdapter)有个隐性要求:用来绑定UI(比如ListView、RecyclerView用Cursor适配的话)的Cursor,必须包含一个名为_id的列。哪怕你自己没在代码里显式调用这个列,适配器内部需要用它来唯一标识每一行数据,处理点击、刷新等逻辑。
给你两种靠谱的解决方案,按需选择:
方案1:修改数据库表结构(推荐,符合Android SQLite规范)
直接在你的表中添加_id列作为主键,这是Android官方推荐的数据库设计方式。比如原来的建表语句:
CREATE TABLE movies ( id INTEGER PRIMARY KEY, title TEXT, release_date TEXT, vote_average REAL, overview TEXT, poster_path TEXT );
可以改成:
CREATE TABLE movies ( _id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER, -- 保留原来的id列(如果业务需要的话) title TEXT, release_date TEXT, vote_average REAL, overview TEXT, poster_path TEXT );
如果你的id本身就是唯一且自增的,也可以直接把id重命名为_id,这样更简洁。
方案2:查询时给现有列起别名(不用改表结构)
如果不想动表结构,就在查询数据的时候,把你现有的id列用AS关键字别名为_id。比如原来的查询语句:
Cursor cursor = db.rawQuery("SELECT id, title, release_date, vote_average, overview, poster_path FROM movies", null);
改成:
Cursor cursor = db.rawQuery("SELECT id AS _id, title, release_date, vote_average, overview, poster_path FROM movies", null);
这样返回的Cursor里就会包含_id列,适配器就能正常工作了。
最后再确认下:你代码里肯定是用了需要Cursor的UI适配器(比如给ListView绑定数据的时候用了CursorAdapter),才会触发这个隐性要求,排查下这部分代码就完全对应上啦。
内容的提问来源于stack exchange,提问作者kav
相关产品推荐
相关产品推荐

