【问题标题】:How to search from SQLite w.r.t a string with single quote and double quotes in Android?如何从 SQLite w.r.t 在 Android 中搜索带有单引号和双引号的字符串?
【发布时间】:2012-04-24 00:16:11
【问题描述】:

我正在通过以下方式使用游标从 Android 查询 SQLite

Cursor searchCusor = getCursorForSearchQuery(str);

其中 str 是一个字符串。此字符串可能包含单引号和双引号。所以当光标试图搜索时会抛出异常

04-12 17:32:11.961: E/AndroidRuntime(2337): FATAL EXCEPTION: main
04-12 17:32:11.961: E/AndroidRuntime(2337): android.database.sqlite.SQLiteException: unrecognized token: "' AND latitude != 0 AND longitude != 0 ORDER BY title ASC": , while compiling: SELECT _id, title FROM node WHERE title LIKE '%'%' AND latitude != 0 AND longitude != 0 ORDER BY title ASC
04-12 17:32:11.961: E/AndroidRuntime(2337):     at android.database.sqlite.SQLiteCompiledSql.native_compile(Native Method)
04-12 17:32:11.961: E/AndroidRuntime(2337):     at android.database.sqlite.SQLiteCompiledSql.compile(SQLiteCompiledSql.java:91)
04-12 17:32:11.961: E/AndroidRuntime(2337):     at android.database.sqlite.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:64)
04-12 17:32:11.961: E/AndroidRuntime(2337):     at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:80)
04-12 17:32:11.961: E/AndroidRuntime(2337):     at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:46)
04-12 17:32:11.961: E/AndroidRuntime(2337):     at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:53)
04-12 17:32:11.961: E/AndroidRuntime(2337):     at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1412)
04-12 17:32:11.961: E/AndroidRuntime(2337):     at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1296)
04-12 17:32:11.961: E/AndroidRuntime(2337):     at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1251)
04-12 17:32:11.961: E/AndroidRuntime(2337):     at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1331)
04-12 17:32:11.961: E/AndroidRuntime(2337):     at com.mid.kew.apies.KewDatabaseHelper.getCursorForSearchMapPage(KewDatabaseHelper.java:285)
04-12 17:32:11.961: E/AndroidRuntime(2337):     at com.mid.kew.activities.MapFragment.getCursorForSearchQuery(MapFragment.java:538)
04-12 17:32:11.961: E/AndroidRuntime(2337):     at com.mid.kew.activities.MapFragment.access$12(MapFragment.java:537)
04-12 17:32:11.961: E/AndroidRuntime(2337):     at com.mid.kew.activities.MapFragment$6.afterTextChanged(MapFragment.java:348)
04-12 17:32:11.961: E/AndroidRuntime(2337):     at android.widget.TextView.sendAfterTextChanged(TextView.java:6271)
04-12 17:32:11.961: E/AndroidRuntime(2337):     at android.widget.TextView$ChangeWatcher.afterTextChanged(TextView.java:6454)
04-12 17:32:11.961: E/AndroidRuntime(2337):     at android.text.SpannableStringBuilder.sendTextHasChanged(SpannableStringBuilder.java:903)
04-12 17:32:11.961: E/AndroidRuntime(2337):     at android.text.SpannableStringBuilder.change(SpannableStringBuilder.java:359)
04-12 17:32:11.961: E/AndroidRuntime(2337):     at android.text.SpannableStringBuilder.change(SpannableStringBuilder.java:275)
04-12 17:32:11.961: E/AndroidRuntime(2337):     at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:438)
04-12 17:32:11.961: E/AndroidRuntime(2337):     at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:415)
04-12 17:32:11.961: E/AndroidRuntime(2337):     at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:28)
04-12 17:32:11.961: E/AndroidRuntime(2337):     at android.view.inputmethod.BaseInputConnection.replaceText(BaseInputConnection.java:583)
04-12 17:32:11.961: E/AndroidRuntime(2337):     at android.view.inputmethod.BaseInputConnection.commitText(BaseInputConnection.java:174)
04-12 17:32:11.961: E/AndroidRuntime(2337):     at com.android.internal.widget.EditableInputConnection.commitText(EditableInputConnection.java:120)
04-12 17:32:11.961: E/AndroidRuntime(2337):     at com.android.internal.view.IInputConnectionWrapper.executeMessage(IInputConnectionWrapper.java:247)
04-12 17:32:11.961: E/AndroidRuntime(2337):     at com.android.internal.view.IInputConnectionWrapper$MyHandler.handleMessage(IInputConnectionWrapper.java:73)
04-12 17:32:11.961: E/AndroidRuntime(2337):     at android.os.Handler.dispatchMessage(Handler.java:99)
04-12 17:32:11.961: E/AndroidRuntime(2337):     at android.os.Looper.loop(Looper.java:144)
04-12 17:32:11.961: E/AndroidRuntime(2337):     at android.app.ActivityThread.main(ActivityThread.java:4937)
04-12 17:32:11.961: E/AndroidRuntime(2337):     at java.lang.reflect.Method.invokeNative(Native Method)
04-12 17:32:11.961: E/AndroidRuntime(2337):     at java.lang.reflect.Method.invoke(Method.java:521)
04-12 17:32:11.961: E/AndroidRuntime(2337):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
04-12 17:32:11.961: E/AndroidRuntime(2337):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
04-12 17:32:11.961: E/AndroidRuntime(2337):     at dalvik.system.NativeStart.main(Native Method)

我尝试如下替换单引号

str.replace("'", "\' ");

但这并没有成功并给出了同样的错误

【问题讨论】:

    标签: android string sqlite quotes double-quotes


    【解决方案1】:

    您还没有展示您的getCursorForSearchQuery 方法的作用,但我猜它只是将值直接包含在SQL 中。不要那样做。使用带有PreparedStatement 的参数化SQL 查询,一切都会好起来的。您当前的错误不仅会消失,而且您还将关闭 SQL 注入攻击漏洞,并且您将能够更好地处理其他数据类型而不会出现转换问题。

    【讨论】:

    • 您好,谢谢您的帮助... 这是 myDatabase.query("node", new String[]{"_id","title"}, "title LIKE \' %" + stringToSearch +"%\' AND latitude != 0 AND longitude != 0" ,null, null,null, "title ASC");你能举一个你建议我的例子吗?
    • 再次感谢您...我尝试了以下行并且成功了... myDatabase.rawQuery("SELECT _id,title FROM node WHERE title LIKE ? AND latitude != 0 AND longitude != 0 ORDER BY title ASC", new String[]{"%"+stringToSearch+"%"});这是你在回答中提到的吗
    • @Raj:嗯,我可能会使用 SQLiteStatement,但这至少是我的意思的种类。您仍然需要考虑如果输入包含“%”符号会发生什么,但至少您不会受到 SQL 注入攻击...
    【解决方案2】:

    我之前用过下面的说法

    myDatabase.query("node", new String[]{"_id","title"}, "title LIKE \'%" + stringToSearch +"%\' AND latitude != 0 AND longitude != 0" ,null, null,null, "title ASC");
    

    这造成了我提到的问题

    所以我将查询修改为

    myDb.query("node", new String[]{"_id","title"}, "title LIKE ? AND latitude != 0 AND longitude != 0" ,new String[]{"%"+stringToSearch+"%"}, null,null, "title ASC");
    

    现在一切正常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-26
      • 2015-10-29
      • 2023-03-31
      • 2013-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多