5

我在 Android 上使用 SQLite。
我曾经ContentProvider从db查询数据。现在,我在尝试使用子查询时遇到了问题ContentResolver

String selection = "cat_id NOT IN ?"
String[] selectionArgs = new String[]{"(SELECT Categories.id FROM Categories)"}
cursor = mResolver.query(getContentUri(), getListColumns(),
                    selection, selectionArgs, orderBy);

这是错误:

08-06 10:32:36.070: E/AndroidRuntime(2151): Caused by: android.database.sqlite.SQLiteException: near "?": syntax error (code 1): , while compiling: SELECT * FROM TRANSACTIONS WHERE cat_id NOT IN ? ORDER BY time_created ASC, id ASC`

我的问题是“我可以使用 selectionArgs 作为子查询吗?”
我的目的是“获取 cat_id 不在类别表中的事务列表”。
谁能帮我?

4

2 回答 2

12

别忘了这里?实际上是一个值的占位符。稍后将由android绑定。

因此,您不会将查询替换为 ?。作为使用 ? 就是保证sql代码不被用户参数注入。

String selection = "cat_id NOT IN ?"
String[] selectionArgs = new String[]{"(SELECT Categories.id FROM Categories)"}
cursor = mResolver.query(getContentUri(), getListColumns(), selection, selectionArgs, orderBy);

相当于你写的东西

String selection = "cat_id NOT IN '(SELECT Categories.id FROM Categories)'"

您要运行的查询实际上是作为一个值运行的,这意味着它 NOT IN '(some value)'不是有效的 sql。

我建议你只是删除 ? 并将其替换为您在 where 参数中将修复它的查询。

你会用 ? 像这样的占位符(如果你知道它不必在里面)。

String selection = "cat_id NOT IN (?, ?)"
String[] selectionArgs = new String[]{"value1", "value2"}
cursor = mResolver.query(getContentUri(), getListColumns(), selection, selectionArgs, orderBy);

编辑:试试

String selection = "cat_id NOT IN (SELECT Categories.id FROM Categories)"
cursor = mResolver.query(getContentUri(), getListColumns(), selection, null, orderBy);
于 2013-08-06T02:01:03.307 回答
2

我给你一个应该工作的例子(在我的例子中更新 ContentResolver 方法):

String selection =  DatabaseContract.EventTable.Column.ID_EVENT + " IN (SELECT DISTINCT "
    + DatabaseContract.CountryEventTable.Column.EVENT_ID + " FROM "
    + DatabaseContract.CountryEventTable.TABLE_NAME + " WHERE "
    + DatabaseContract.CountryEventTable.Column.COUNTRY_CODE + "=?)";

String [] selectionArgs = new String[]{
    data[0],
};
于 2013-12-18T11:55:59.913 回答