【问题标题】:Gotchas INSERTing into SQLite on Android?在 Android 上插入 SQLite 的陷阱?
【发布时间】:2010-04-05 05:30:34
【问题描述】:

我正在尝试在 Android 中设置一个简单的 SQLite 数据库,通过 SQLiteOpenHelper 的子类处理架构。但是,当我查询我的表时,我认为我插入的列永远不会出现。

也就是说,在 SQLiteOpenHelper 的 onCreate(SQLiteDatabase db) 方法中,我使用 db.execSQL() 运行 CREATE TABLE 命令,然后尝试了 db.execSQLdb.insert() 在我刚刚创建的表上运行 INSERT 命令。这似乎运行良好,但是当我尝试查询它们时,我总是返回 0 行(为了调试,我正在运行的查询很简单 SELECT * FROM table 并检查光标的 getCount())。

以前有人遇到过这样的事情吗?这些命令似乎在命令行 sqlite3 上运行。它们是我遗漏的问题吗(例如 INSERTS 必须/不得以分号结尾,或者涉及多个表的某些问题)?我附上了下面的一些代码。

感谢您的宝贵时间,如果我可以进一步澄清,请告诉我。


@Override
public void onCreate(SQLiteDatabase db)
{
    db.execSQL("CREATE TABLE "+ LEVEL_TABLE +" (" + 
               "  "+ _ID +" INTEGER PRIMARY KEY AUTOINCREMENT," +
               "  level TEXT NOT NULL,"+
               "  rows INTEGER NOT NULL,"+
               "  cols INTEGER NOT NULL);");

    db.execSQL("CREATE TABLE "+ DYNAMICS_TABLE +" (" + 
               "  level_id INTEGER NOT NULL," +
               "  row INTEGER NOT NULL,"+
               "  col INTEGER NOT NULL,"+
               "  type INTEGER NOT NULL);");

    db.execSQL("CREATE TABLE "+ SCORE_TABLE +" (" + 
               "  level_id INTEGER NOT NULL," +
               "  score INTEGER NOT NULL,"+
               "  date_achieved DATE NOT NULL,"+
               "  name TEXT NOT NULL);");
    this.enterFirstLevel(db);
}

还有一个我当前使用的插入代码示例,它在enterFirstLevel() 中调用(一些值硬编码只是为了让它运行...):

private void insertDynamic(SQLiteDatabase db, int row, int col, int type)
{
    ContentValues values = new ContentValues();

    values.put("level_id", "1");
    values.put("row", Integer.toString(row));
    values.put("col", Integer.toString(col));
    values.put("type", Integer.toString(type));

    db.insertOrThrow(DYNAMICS_TABLE, "col", values);
}

最后,查询代码如下:

private Cursor fetchLevelDynamics(int id)
{
    SQLiteDatabase db = this.leveldata.getReadableDatabase();
    try {
        String fetchQuery = "SELECT * FROM " + DYNAMICS_TABLE;
        String[] queryArgs = new String[0];         
        Cursor cursor = db.rawQuery(fetchQuery, queryArgs);

        Activity activity = (Activity) this.context;
        activity.startManagingCursor(cursor);
        return cursor;
    }
    finally {
        db.close();
    }
}

【问题讨论】:

    标签: android sqlite


    【解决方案1】:

    想通了,这是一些不同的事情。首先,查询代码:Cursor 只能浏览开放数据库。所以上面的查询方法会返回一个Cursor,然后在finally块中关闭数据库。

    虽然它不能正常工作,但如果在关闭的数据库下操作,光标不会抛出错误。它只会说它返回了 0 行(这就是为什么我认为错误在 INSERT 代码中)。

    另外,我忘记了一些 SQL 的东西,即 rowcol 不是表字段的好名字,我可以通过将它们重命名为 row_num 和 @987654325 来消除一些错误@

    【讨论】:

      【解决方案2】:

      在我看来还不错。

      为了解决问题,我建议在您的 queryArgs 中添加至少一列。我不确定发送空列表的效果。这可能会导致即使有结果也不会返回任何行。

      在 ContentValues 中不必将 Integer 值转换为字符串。尝试用 values.put("row", row); 替换 values.put("row", Integer.toString(row)); 可能不是问题的原因,因为如果它反对字符串,它会引发异常。

      我没用过SQLiteDatabase.rawQuery(),也许试试更常用的.query()?

      我看不到你的代码对 fetchLevelDynamics() 返回的“光标”做了什么,所以我不能排除那里的逻辑错误。

      【讨论】:

      • 虽然这在技术上不是答案(我找到了它,并将其作为问题的单独答案写出来),但我很欣赏调试技巧,希望将问题标记为已回答,并给出你的声望点。谢谢你的帮助^_^
      【解决方案3】:

      尝试使用null作为第二个参数

      db.insertOrThrow(DYNAMICS_TABLE, "col", values);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多