我正在尝试执行一个具有各种条件的查询,并且我遇到了异常。
bind or column index out of range
以下是来自ContentProvider的查询。
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
int uriType = sURIMatcher.match(uri);
switch (uriType) {
case RESPONSEVIEW2_SELECTION_10:
queryBuilder.setTables(RESPONSES_VIEW);
String activeUserKey = getActiveUserId();;
String outerSelection =
"(((" + PeerCreatedDataColumns.SHARED + "=" + "" + trueId + "" + ") OR "
+ "(" + PeerCreatedDataColumns.AUTHORHASH + "=" + "'" + activeUserKey + "'" + ")) AND ("
+ "(" + ResponsesColumns.PRIMARYMATCH + "= '*'" + ") OR "
// '*' is defined by the program, hopefully not in conflict with anything built-in
+ "(" + ResponsesColumns.PRIMARYMATCH + " like '?') OR "
+ "(" + ResponsesColumns.PRIMARYMATCH + " like '" + selectionArgs[0] + "%') OR "
+ "(" + ResponsesColumns.PRIMARYMATCH + " like '%" + selectionArgs[0] + "') OR "
+ "(" + ResponsesColumns.PRIMARYMATCH + " like '%" + selectionArgs[0] + "%'" + ")))";
Log.d(DEBUG_TAG, "query " + outerSelection);
Cursor cursor10 = queryBuilder.query(mDB.getReadableDatabase(), projection, outerSelection, selectionArgs,
null, null, sortOrder);
cursor10.setNotificationUri(getContext().getContentResolver(), uri);
Log.e(DEBUG_TAG, "responses_view2 should have better search function");
return cursor10;
case ROW_SELECTION_11:
queryBuilder.setTables(RESPONSES_VIEW);
Log.e(DEBUG_TAG, "responses_view2 should have better search function");
queryBuilder.appendWhere(PeerDatabase._ID + "=" + uri.getLastPathSegment());
Cursor cursor11 = queryBuilder.query(mDB.getReadableDatabase(), projection, selection, selectionArgs, null,
null, sortOrder);
cursor11.setNotificationUri(getContext().getContentResolver(), uri);
return cursor11;
...
}
}
这是Cursor Loader,它似乎是错误的来源。
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
if (search == null) {
return null;
} else {
String[] selectArgs = { search };
return new CursorLoader(getActivity(), table, createProjection, "?", selectArgs, null);
}
}
以下是整个错误:
12-09 18:25:54.509: E/AndroidRuntime(12461): FATAL EXCEPTION: ModernAsyncTask #2
12-09 18:25:54.509: E/AndroidRuntime(12461): java.lang.RuntimeException: An error occured while executing doInBackground()
12-09 18:25:54.509: E/AndroidRuntime(12461): at android.support.v4.content.ModernAsyncTask$3.done(ModernAsyncTask.java:137)
12-09 18:25:54.509: E/AndroidRuntime(12461): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
12-09 18:25:54.509: E/AndroidRuntime(12461): at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
12-09 18:25:54.509: E/AndroidRuntime(12461): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
12-09 18:25:54.509: E/AndroidRuntime(12461): at java.util.concurrent.FutureTask.run(FutureTask.java:138)
12-09 18:25:54.509: E/AndroidRuntime(12461): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
12-09 18:25:54.509: E/AndroidRuntime(12461): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
12-09 18:25:54.509: E/AndroidRuntime(12461): at java.lang.Thread.run(Thread.java:1019)
12-09 18:25:54.509: E/AndroidRuntime(12461): Caused by: android.database.sqlite.SQLiteException: bind or column index out of range: handle 0x28bd08
12-09 18:25:54.509: E/AndroidRuntime(12461): at android.database.sqlite.SQLiteProgram.native_bind_string(Native Method)
12-09 18:25:54.509: E/AndroidRuntime(12461): at android.database.sqlite.SQLiteProgram.bindString(SQLiteProgram.java:244)
12-09 18:25:54.509: E/AndroidRuntime(12461): at android.database.sqlite.SQLiteQuery.bindString(SQLiteQuery.java:185)
12-09 18:25:54.509: E/AndroidRuntime(12461): at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:48)
12-09 18:25:54.509: E/AndroidRuntime(12461): at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1356)
12-09 18:25:54.509: E/AndroidRuntime(12461): at android.database.sqlite.SQLiteQueryBuilder.query(SQLiteQueryBuilder.java:330)
12-09 18:25:54.509: E/AndroidRuntime(12461): at android.database.sqlite.SQLiteQueryBuilder.query(SQLiteQueryBuilder.java:280)
12-09 18:25:54.509: E/AndroidRuntime(12461): at org.anuvar.plana.m.provider.PeerDataProvider.query(PeerDataProvider.java:285)
12-09 18:25:54.509: E/AndroidRuntime(12461): at android.content.ContentProvider$Transport.query(ContentProvider.java:187)
12-09 18:25:54.509: E/AndroidRuntime(12461): at android.content.ContentResolver.query(ContentResolver.java:262)
12-09 18:25:54.509: E/AndroidRuntime(12461): at android.support.v4.content.CursorLoader.loadInBackground(CursorLoader.java:49)
12-09 18:25:54.509: E/AndroidRuntime(12461): at android.support.v4.content.CursorLoader.loadInBackground(CursorLoader.java:35)
12-09 18:25:54.509: E/AndroidRuntime(12461): at android.support.v4.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:240)
12-09 18:25:54.509: E/AndroidRuntime(12461): at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:51)
12-09 18:25:54.509: E/AndroidRuntime(12461): at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:40)
12-09 18:25:54.509: E/AndroidRuntime(12461): at android.support.v4.content.ModernAsyncTask$2.call(ModernAsyncTask.java:123)
12-09 18:25:54.509: E/AndroidRuntime(12461): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
12-09 18:25:54.509: E/AndroidRuntime(12461): ... 4 more
我正在尝试找出异常,但如果有更好的方法来查询此数据,请告诉我。
答案 0 :(得分:4)
?
参数中selection
的数量必须与selectionArgs
参数中的字符串数相匹配。 LogCat表明这些计数不匹配,但我们很难说......
我发现了问题,请不要将?
括在引号中,否则你就是在搜索问号。这是不正确的:
" like '?') OR "
改为使用:
" like ?) OR "
如果search
是用户输入,则应该保护自己免受SQL注入攻击:
+ "(" + ResponsesColumns.PRIMARYMATCH + " like ?) OR "
+ "(" + ResponsesColumns.PRIMARYMATCH + " like ?) OR "
+ "(" + ResponsesColumns.PRIMARYMATCH + " like ?) OR "
+ "(" + ResponsesColumns.PRIMARYMATCH + " like ?)))";
并创建一个新的selectionArgs
参数,如下所示:
String search = selectionArgs[0];
String[] matchArgs = { search, search + "%", "%" + search, "%" + search + "%" };
Cursor cursor10 = queryBuilder.query(mDB.getReadableDatabase(), projection,
outerSelection, matchArgs, null, null, sortOrder);