Android SQLite查询报no such column: CollectionId错误求助
Android SQLite "no such column: CollectionId" 报错排查
问题现象
- 应用初始阶段完成数据库设计搭建,后续执行数据库查询操作时抛出
no such column: CollectionId错误,同步提示OS error - 11:Try again - 升级数据库版本后问题仍未解决
关联代码片段
数据库表定义代码
public static String TABLE_NAME = "CollectionPhoto"; public static String COLLECTION_ID = "CollectionId"; public static String FILE_NAME = "FileName"; public static String FILE_NAME_SAMPLE = "FileNameSample"; public static String DESCRIPTION = "Description"; public static void createTable(SQLiteDatabase db) { db.execSQL("drop table if exists " + TABLE_NAME); db.execSQL("create table " + CollectionPhotoTable.TABLE_NAME + " (" + "_id integer primary key autoincrement," + CollectionPhotoTable.COLLECTION_ID + " text," + CollectionPhotoTable.DESCRIPTION + " text," + CollectionPhotoTable.FILE_NAME + " text," + CollectionPhotoTable.FILE_NAME_SAMPLE + " text);"
报错位置代码
public Cursor cursor(String _collectionId) { return GlobalVars.db.rawQuery("select * from CollectionPhoto where CollectionId = ? ", new String[]{_collectionId}); }
DBHelper实现代码
void createTables(SQLiteDatabase db) { CollectionPhotoTable.createTable(db); } static void deleteTables(SQLiteDatabase db) { db.beginTransaction(); db.execSQL("drop table if exists CollectionPhoto"); db.endTransaction(); } @Override public void onCreate(SQLiteDatabase db) { createTables(db); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { deleteTables(db); createTables(db); }
完整报错日志
Caused by: android.database.sqlite.SQLiteException: no such column: CollectionId (Sqlite code 1 SQLITE_ERROR): , while compiling: select * from CollectionPhoto where CollectionId = ?, (OS error - 11:Try again)
问题根因
- 事务逻辑错误导致表结构更新失效:
deleteTables方法中开启事务后执行删表操作,但未调用setTransactionSuccessful()标记事务成功,调用endTransaction()时所有操作会默认回滚,删表操作实际未生效。后续执行建表语句时,因同名旧表已存在,建表操作静默失败,无CollectionId字段的旧表被保留。 - 全局静态数据库实例阻塞升级流程:代码中使用
GlobalVars.db全局静态缓存数据库实例,若该实例在旧版本数据库结构下初始化完成后未被释放,会一直持有数据库连接,触发版本升级时数据库被加锁,onUpgrade中的删表、建表操作因锁冲突执行失败,同时会抛出OS error -11: Try again的资源重试提示。 - 建表SQL存在截断风险:贴出的
createTable方法代码不完整,建表SQL拼接后存在语法缺失可能,若建表语句执行中途报错中断,会残留不完整的旧表结构。
修复方案
- 修正事务逻辑,所有开启的事务必须在操作成功后标记成功,用try-finally块保证事务正常结束:
static void deleteTables(SQLiteDatabase db) { db.beginTransaction(); try { db.execSQL("drop table if exists CollectionPhoto"); db.setTransactionSuccessful(); } finally { db.endTransaction(); } } - 废弃全局静态缓存的数据库实例,每次执行数据库操作前通过
SQLiteOpenHelper.getWritableDatabase()/getReadableDatabase()获取实例,保证数据库升级后能拿到最新连接,避免锁冲突。 - 补全建表SQL语法,执行建表后可通过
PRAGMA table_info(CollectionPhoto)指令校验字段完整性,确认CollectionId字段存在后再执行业务查询。 - 修复完成后可通过清除应用数据或卸载重装的方式,触发全量建表流程,验证问题是否解决。
内容的提问来源于stack exchange,提问作者Darsi
相关产品推荐
相关产品推荐

