【问题标题】:Android database rawQuery: strange Cursor behaviourAndroid数据库rawQuery:奇怪的游标行为
【发布时间】:2017-03-03 11:02:00
【问题描述】:

升级前我需要检查数据库中的表。

我在自己的 DatabaseHelper 中覆盖了SQLiteOpenHelper.onUpgrade(SQLiteDatabase db, int oldVer, int newVer),以便在数据库版本增加时完成这项工作。

我在 sqlite_master 表上使用此查询来获取表名:select * from sqlite_master 但即使 cursor.getCount()==29 游标似乎为空(DB 不为空,包含 29 个对象)

同样的查询在我的 APP 的其他地方也很有效。

我正在模拟的 Android 4.4 (api 19) 上对此进行测试,而我的应用是用

构建的
minSdkVersion 12
targetSdkVersion 24

对这种奇怪的行为有任何想法吗?

代码如下:

public class DatabaseHelper extends SQLiteOpenHelper {

    public static DatabaseHelper getHelper(Context context) {
        if (instance == null)
            synchronized( DatabaseHelper.class ) {
                if( instance==null )
                    instance = new DatabaseHelper(context.getApplicationContext());
            }

        return instance;
    }

    private DatabaseHelper(Context c) {
        super(c, DB_NAME, null, 6 /* version */);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 
        final boolean inTransaction = db.inTransaction();

        if( !inTransaction )
            db.beginTransaction();

        Cursor cur = null;

        try {
//          cur = db.query("sqlite_master", null, null, null, null, null, null); // SAME BEHAVIOUR
            cur = db.rawQuery("select * from sqlite_master", null );

            int count = cur.getCount(); // ASSIGN 29 TO COUNT
            while( cur.moveToNext()) {
                ** NEVER ENTERS HERE **
            }

            if( !inTransaction )
                db.setTransactionSuccessful();

        } catch (Exception e) {
            log.e(DBTAG, e.getMessage(), e);
        } finally {
            if( cur!=null)
                cur.close();

            if( !inTransaction )
                db.endTransaction();
        }
    }
}

【问题讨论】:

  • 我认为你应该使用 cursor.moveToFirst();首先

标签: android database sqlite cursor


【解决方案1】:

我刚刚重构了你的案例,发现“sqlite”是保留给内部使用的,下面是我得到的错误信息。

android.database.sqlite.SQLiteException:对象名称保留供内部使用:sqlite_master

也许你可以尝试另一个表名,看看它是否可以工作。

【讨论】:

  • 我曾经查询过 sqlite_master,但从来没有得到“android.database.sqlite.SQLiteException: object name reserved for internal use: sqlite_master”。我尝试将查询移动到不同的地方并且有效!
  • 只有在创建新对象时才会出现此错误消息,而不是使用 SELECT。
【解决方案2】:

我发布的代码位于库模块中。 当我将它移到主应用程序模块中时,sqlite_master 上的查询起作用了!

我在 app 模块和库模块中将 build.gradle 中的 buildToolsVersion 从 24.0.2 升级到了 24.0.3。然后完全重建。

我不知道为什么,但是……现在查询可以在主模块或库模块中工作!

【讨论】:

    猜你喜欢
    • 2012-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-03
    • 2012-02-13
    相关资源
    最近更新 更多