【问题标题】:Can't extract integer from cursor after preforming sqlite query in Android在Android中执行sqlite查询后无法从光标中提取整数
【发布时间】:2017-07-12 23:56:47
【问题描述】:

我正在开发一个小型 Android 应用程序,该应用程序维护一个小型工具数据库,我借给其他人使用。

作为应用程序的一部分,我正在合并一个 sqllite 数据库,在执行查询和使用游标后,我在执行查询时遇到了一些麻烦。

有问题的代码如下:

    String COLUMN_NAME = "toolName";
    String[] columns = { COLUMN_NAME };
    String selection = COLUMN_NAME + " =?";
    String[] selectionArgs = {tool};

    Cursor cursor = mToolDb.query(ToolStatisticContract.ToolStatisticEntry.TABLE_NAME, columns, 
    selection, selectionArgs, null, null, null, null);

    return Integer.parseInt(cursor.getString(3));

数据库的合约如下:

    public class ToolStatisticContract {
        public static final class ToolStatisticEntry implements BaseColumns {
        public static final String TABLE_NAME = "tooltable";
        public static final String COLUMN_TOOL_NAME = "toolName";
        public static final String COLUMN_LIFESPAN = "lifespan";
        public static final String COLUMN_USAGE = "usageTime";
    }
}

我实际上是在尝试从 COLUMN_USAGE 中提取值,这似乎会在将值解析为整数时产生错误。 COLUMN 中的值实际上是一个整数类型转换为上一段代码中的字符串,所以我相当确定错误包含在上面的代码 sn-ps 中。

再次提前感谢您的所有帮助!

【问题讨论】:

    标签: android database sqlite cursors


    【解决方案1】:

    有问题的代码如下

    net SQL 语句是这样的:

    SELECT toolName FROM tooltable WHERE toolName = ?
    

    并且没有索引为 3 的列,因为您只返回 1 列。

    你需要:

    • 在您的列列表中有usageTime (COLUMNS)
    • Cursor 移动到有效行(因为它最初位于第一行之前)
    • 通过getInteger()COLUMNS对齐的值来检索usageTime

    【讨论】:

    • 您好,非常感谢您的回复。因此,根据我的(有限)理解,我应该修改 COLUMNS [] 以便只存在 usageTime ,因为那是我实际需要的列。
    • 在将光标移动到有效行方面,database.query 函数不是已经完成了吗?
    • @GoatHerder 不,当您获得光标时,它位于第一行之前。这是因为不包含行的游标作为游标是有效的。
    • 对!好的,所以基本上我在查询之后,我必须将它移到第一行,然后才能调用 getInteger() 或其他任何东西。我这样说对吗?
    • @GoatHerder,是的,我添加了一个答案,展示了如何做到这一点。
    【解决方案2】:

    您可以使用以下内容。这使用 null 而不是列,它将获取所有列(即解析为 SELECT * FROM table)。它检查是否已返回一行,然后才尝试获取数据。它还会关闭游标(完成后您应该关闭游标)。它使用cursor.getInt() 来获取整数值,而不是将其从字符串转换为整数。它假定您只会得到 1 行(如果没有行,则返回 0)。

    int returnvalue = 0;
    String COLUMN_NAME = "toolName";
    String[] columns = { COLUMN_NAME };
    String selection = COLUMN_NAME + " =?";
    String[] selectionArgs = {tool};
    
    Cursor cursor = mToolDb.query(ToolStatisticContract.ToolStatisticEntry.TABLE_NAME, null, 
    selection, selectionArgs, null, null, null, null);
    
    if (cursor.getCount() > 0) {
        cursor.moveToFirst();
        returnvalue = cursor.getInt(2);
        //or returnvalue = Integer.parseInt(cursor.getString(2));
    }
    cursor.close();
    return returnvalue;
    

    注意!我没有检查这个只是从内存中编码的,所以为奇怪的错误道歉。

    要使用特定列执行上述操作,您可以使用:-

    String COLUMN_NAME = "toolName";
    String[] columns = { COLUMN_USAGE };
    String selection = COLUMN_NAME + " =?";
    String[] selectionArgs = {tool};
    
    Cursor cursor = mToolDb.query(ToolStatisticContract.ToolStatisticEntry.TABLE_NAME, columns, 
    selection, selectionArgs, null, null, null, null);
    

    在这种情况下,列索引将为 0(即索引是根据游标中的列的索引)。但是最好使用以下方法,根据列名获取列索引:-

    cursor.getInt(cursor.getColumnIndex(COLUMN_USAGE);
    

    【讨论】:

      【解决方案3】:

      从数据库中读取单个值的最简单方法是使用helper function,这样您就可以避免处理游标对象:

      String query = "SELECT usageTime FROM tooltable WHERE toolName = ?";
      String[] selectionArgs = { tool };
      long returnvalue = DatabaseUtils.longForQuery(mToolDb, query, selectionArgs);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-08-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多