【问题标题】:Inconsistent results on Android SQLite queryAndroid SQLite 查询结果不一致
【发布时间】:2015-04-08 07:36:14
【问题描述】:

我在 Android 上的 SQL 查询结果遇到一些意外的不一致。

给定以下 Schema(非常简单):

public static final String TABLE_TOTD = "totd";
public static final String COLUMN_ID = "id";
public static final String COLUMN_TG = "tg";
public static final String COLUMN_EX = "ex";

private static final String DATABASE_NAME = "TOTD.db";

private static final String DATABASE_CREATE = "CREATE TABLE "
        + TABLE_TOTD + "("
            + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
            + COLUMN_TG + " TEXT NOT NULL, "
            + COLUMN_EX + " TEXT"
        + ");";

数据库正在初始化并填充了一些示例文本:

    SQLiteDatabase db = mdbHelper.getWritableDatabase();

    ContentValues values = new ContentValues();
    values.put(MySQLiteHelper.COLUMN_TG, "This is a text (1)");
    values.put(MySQLiteHelper.COLUMN_EX, "Example goes here");

    db.insert(MySQLiteHelper.TABLE_TOTD, null, values);
    [...]

使用 SQLiteDatabase.query() 查询时检索到不一致的结果 下面的代码通过返回一个带有表格第一行的 Cursor 来完成预期的工作。

    String[] projection = null;
    String selection = "id = 1";
    String[] selectionArgs = null;
    Cursor cursor = db.query(
            MySQLiteHelper.TABLE_TOTD,
            projection,
            selection,
            selectionArgs,
            null, null, null);

通过像这样更改selection 和selectionArgs,它的工作原理完全相同:

    String selection = "id = ?";
    String[] selectionArgs = {"1"};

但现在,与预期不同的是,通过执行以下更改,返回的光标现在将为空:

    String selection = "? = ?";
    String[] selectionArgs = {"id", "1"};

实际上,尝试将不是"1" 的任何内容推入参数将导致查询返回空游标。

我尝试了以下方法:

    String selection = "? = 1";
    String[] selectionArgs = {"id"};

    String selection = "id ? 1";
    String[] selectionArgs = {"="};

    String selection = "?";
    String[] selectionArgs = {"id = 1"}; //This is where I couldn't take it anymore...

现在,我对任何形式的解释都持开放态度。我的代码有效,而且我知道我可以将所有参数放在 selection 字符串上,因为它们不包含任何禁止字符。 我只是想知道,为什么它不起作用,为什么开发者文档中没有提到这个明确的限制?

【问题讨论】:

    标签: android database sqlite android-database


    【解决方案1】:

    选择参数是您的 sqlite 查询的 WHERE 子句。当您使用 ? 执行查询时它将在 selectionArgs 字符串数组中查找此参数。但是,您只能将值指定为 ?而不是关键。几个有效的例子:

    String selection = "id = ?";
    String[] selectionArgs = new String[]{"1"};
    

    类似于

    String selection = "id = 1";
    String[] selectionArgs = null;
    

    但是你做不到

    String selection = "? = ?";
    

    您还可以指定多个 ?在选择中。

    String selection = "id = ? AND carId = ?";
    String[] selectionArgs = new String[]{"1", "2"};
    

    来自文档:

    您可以在选择中包含 ?s,它将被值替换 来自 selectionArgs,以便它们出现在选择中。这 值将绑定为字符串。

    http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#query(boolean, java.lang.String, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String)

    【讨论】:

    • 在select 语句中只能替换值是有道理的,但是文档中没有很好地解释这种行为......我已经习惯了类似C字符串格式,我没想到这个特定调用会出现这些限制。
    猜你喜欢
    • 1970-01-01
    • 2014-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多