錯誤堆棧
android.database.sqlite.SQLiteException: bind or column index out of range
問題 SQL 片段
String outerSelection = "... PRIMARYMATCH like '?') OR " // 錯誤:單引號包裹佔位符
+ " PRIMARYMATCH like '" + selectionArgs[0] + "%') OR " // 拼接參數,非佔位符
根本原因
'?' 被單引號包裹,SQLite 視為字面字符串 ? 而非佔位符,導致佔位符數量與 selectionArgs 不匹配。
- 部分條件直接拼接參數值,存在 SQL 注入風險且佔位符計數錯亂。
修正:統一使用佔位符並構建參數數組
String selection = "(" + Columns.PRIMARY_MATCH + " = ?) OR "
+ "(" + Columns.PRIMARY_MATCH + " LIKE ?) OR "
+ "(" + Columns.PRIMARY_MATCH + " LIKE ?) OR "
+ "(" + Columns.PRIMARY_MATCH + " LIKE ?)";
String search = selectionArgs[0];
String[] args = { "*", search + "%", "%" + search, "%" + search + "%" };
Cursor cursor = queryBuilder.query(db, projection, selection, args, null, null, sortOrder);
最佳實踐
- 所有動態值統一用
? 佔位符,不要 加引號。
- 參數數組順序與 SQL 中
? 出現順序一一對應。
- 使用
SQLiteQueryBuilder 簡化複雜查詢構建。
- 開啟
SQLiteDatabase.enableSqlTracing() 或 adb shell setprop log.tag.SQLiteStatements VERBOSE 調試 SQL 執行情況。