【问题标题】:How To Test If Cursor Is Empty in a SQLiteDatabase Query如何测试 SQLiteDatabase 查询中的光标是否为空
【发布时间】:2011-11-05 13:51:00
【问题描述】:

我有一个由以下代码创建的 SQL 表:

public void onCreate(SQLiteDatabase db) {
    db.execSQL("CREATE TABLE " + TABLE_NAME + " (" + _ID
        + " INTEGER PRIMARY KEY AUTOINCREMENT, " + SUBJECT
        + " TEXT NOT NULL," + TOPIC + " TEXT NOT NULL, "
        + LECTURENUMBER + " TEXT NOT NULL, " + PAGENUMBER
        + " TEXT NOT NULL, " + DATE + " TEXT NOT NULL, " + _DATA
        + " TEXT NOT NULL);");
}

我查询表如下:

String sql = "SELECT " + _ID + "," + SUBJECT + " FROM " + TABLE_NAME
    + " GROUP BY " + SUBJECT + ";";

Cursor cursor = subjects.getReadableDatabase().rawQuery(sql, null);

问题是,如果光标为空(即表不存储任何值),我必须启动 Activity A,如果光标不为空(即表已填满),我必须启动 Activity B。

我找不到可以告诉我表是否为空的方法。 我尝试使用 Log 如下:

private void showSubjectsOnList() {
    String sql = "SELECT " + _ID + "," + SUBJECT + " FROM " + TABLE_NAME
        + " GROUP BY " + SUBJECT + ";";

    Cursor cursor = subjects.getReadableDatabase().rawQuery(sql, null);

    Log.d("Events",Integer.toString(cursor.getCount()));
    if(cursor.isNull(0)!=false){
        cursor.close();
        subjects.close();
        startActivity(new Intent(this,OpenScreen.class));
    }
}

但是 LOG 显示 1,如果表为空...再次显示 1,如果表有 1 个条目....它显示 2,如果表有两个条目,依此类推。

您能否建议一些方法来解决我根据光标是否为空来启动不同活动的问题。

【问题讨论】:

    标签: java android sqlite android-cursor


    【解决方案1】:

    像这样测试光标怎么样,然后按照你说的做:

    if(cursor!=null && cursor.getCount()>0)
    

    getCount()

    返回游标中的行数

    http://developer.android.com/reference/android/database/Cursor.html#getCount()

    【讨论】:

    • 我没有完全按照你提到的方式尝试过。但我也尝试使用 cursor!=null,如下所示: Log.d("Events",Boolean.toString(cursor!=null));有趣的是,如果表有一些值,则 Log 显示为 true,但令人惊讶的是,如果表为空,则根本不显示日志。我很困惑这是什么意思。
    • 在测试之前不要忘记将光标的指针移动到带有cursor.moveToFirst()的第一条记录
    • 这意味着您的查询返回零行。这意味着游标不为空,但有零行:D
    • 是的,我把它移到了 firstRow 并使用了 if(cirsor!=null && cursor.getCount()>0) 它不起作用 =s。
    • @Nikoli,但 getCount 在 Log 中显示为 1,即使表为空,这是最让我生气的事情。
    【解决方案2】:

    测试空游标的最简单和最简洁的方法是以下代码:

    if ( cursor.moveToFirst() ) {
        // start activity a
    } else {
        // start activity b
    }
    

    根据文档,如果光标为空,该方法返回 false:

    http://developer.android.com/reference/android/database/Cursor.html#moveToFirst%28%29

    public abstract boolean moveToFirst()

    在 API 级别 1 中添加 将光标移动到第一行。

    如果光标为空,此方法将返回 false

    返回移动是否成功。

    【讨论】:

    • cursor.moveToNext () 怎么样...我认为如果有行返回 true,如果没有找到行返回 false...
    【解决方案3】:

    您只需要使用 getCount()。 如果您的 sql 正确但不返回任何行,您将有一个 NOT null 游标对象但没有行,getCount() 将返回 0。

    【讨论】:

    • 查询数据库时始终返回游标对象。例如,它里面有你的查询字符串。所以它不能为空:在 Java 中 - 未“连接”到任何对象的标识符为空。只有当您的选择查询没有返回任何行时 - getCount() 才会返回零。
    • 嗯..好的...感谢您的详细说明。但是我该如何解决我的问题呢?
    • 检查查询。我现在可以看到一个错误:不能用; 关闭查询。 developer.android.com/reference/android/database/sqlite/…
    【解决方案4】:

    删除的记录作为空记录保留在 SQLite 中,但 getCount() 只计算不空记录。如果您的表有一些为空的记录,则一些非空记录的_Id 数字将大于getCount() 的结果。要到达它们,您可以迭代游标(使用 for() 循环)两倍于 getCount() 的结果的次数,并使用游标将 record_Id 数字填充到数组中。假设结果数组是{ 1, 2, 5, 6, 7, 8, 9, 11, 12, 14 }

    这意味着记录 3、4、10、13 是空记录,并且您的表总共有 14 条记录,而不是您从 getCount() 获得的 10 条记录。

    记住:

    1. getCount() 返回非空记录数,
    2. 游标返回_Id非空记录数,
    3. _Id 游标“遗漏”的数字是 _Id 空记录数,
    4. 必须达到比getCount() 足够远的距离才能获取所有信息。

    【讨论】:

      【解决方案5】:

      我的建议是使用ListActivity

      这些是用于在ListView 中显示项目的活动。您可以简单地使用SimpleCursorAdapter 来填充它们(在ListActivitys JavaDoc 页面中也有说明)。

      他们还提供setEmptyView()-method,可用于显示View(可能是TextView),通知用户尚无记录以及如何创建记录。

      可以在here 找到有关如何执行此操作的示例。

      【讨论】:

      • 亲爱的 Lukas,活动 B 实际上是 listActivity。甚至上面提到的方法showSubjectsOnList()也是这个Activity中的一个方法。如果 ShowSubjectsOnList 中的光标为空,我想启动 Activity A,否则我想留在同一个 Activity 中.....但是我无法找到如何找到该光标为空。
      • 嘿 Lukas,我得到了提示。如果setEmptyView()方法可以在listView上设置背景,我就不用启动新的Activity B了,因为使用Activity B的实际目的是为了避免空List给人的感觉不好......让我试试setEmptyView 方法及其用法。
      【解决方案6】:

      我相信您的问题是您没有创建正确的查询。

      您应该使用 SQLiteDatabase 查询。

      Cursor c = db.query(TABLE_NAME, null,
                  null, null, null, null, null);
      

      然后您可以使用 c.getCount() 来确定表是否有任何内容。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-27
        • 2011-09-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多