代码之家  ›  专栏  ›  技术社区  ›  lxknvlk

android SQLiteException:定制ROM上没有这样的列

  •  1
  • lxknvlk  · 技术社区  · 7 年前

    在修改了android版本的设备上,我会遇到这个错误。比如小米设备。

    String query = "select * from dialogues where userId = ? and topChat = 0 order by updatedAtByClient desc";
    Cursor dialogRes = db.rawQuery(query, new String[]{userId});
    

    这里我有一个例外:

    android.database.sqlite.SQLiteException: no such column: topChat (code 1):,
    while compiling: select * from dialogues where userId = ? and topChat = 0 
    order by updatedAtByClient desc
    

    我手工编写了异常消息,因为用户在屏幕截图中向我发送了异常消息,所以可能会出现拼写错误。

    如何解决这个问题,为什么会发生这种情况?

    UPD1: create table语句如下所示:

    "CREATE TABLE IF NOT EXISTS dialogues(fieldName VARCHAR, camelCaseFieldName VARCHAR,
    topChat INTEGER, createdAt DATE);";
    

    我有一个正确实现的更新方法,当我改变数据库结构时,但是这个特定的表和字段名很长时间没有改变。

    UPD2: 我为有问题的用户制作了一个apk,记录了该表的列,我确实在日志中看到了有问题的列,用户说这个版本运行正常。

    所以,这种错误似乎不会100%地发生。很奇怪。也许有一种方法可以在创建数据库后检查其完整性,并重新创建有错误的表?

    1 回复  |  直到 7 年前
        1
  •  0
  •   Martin Zeitler    7 年前

    我不相信这会是一场灾难 xiaomi 问题这似乎是一次不幸的迁移的结果,在迁移过程中,没有添加新的列,随后,用户可能仍然使用表的早期版本。没有其他逻辑解释来解释缺席的列),仅仅是因为 CREATE TABLE 声明有效——也可能无效。

    人们仍然可以用它来解决这个问题 ALTER TABLE 那是什么时候 SQLiteException 发生, addColumnIfNotExists("dialogues", "topChat", "INTEGER DEFAULT 0"); ...为了避免由于缺少某些列而删除表而导致数据丢失。

    public void addColumnIfNotExists(String tableName, String columnName, String dataType) {
        Cursor cursor = null;
        try {
            cursor = db.rawQuery("SELECT * FROM " + tableName, null);
            if(! Arrays.asList(cursor.getColumnNames()).contains(columnName)) {
                db.execSQL(String.format("ALTER TABLE %s ADD COLUMN %s %s", tableName, columnName, dataType));
            }
        } finally {
            if(cursor != null) {
                cursor.close();
            }
        }
    }