2

我在 android sqlite 中创建表。我的表是类别:

db.execSQL("CREATE TABLE IF NOT EXISTS category (id_category INTEGER PRIMARY KEY AUTOINCREMENT,sub INT(5),name VARCHAR ,father INT(5),income_bool INT(1));");

现在我创建一个变量:

String a="بنزین"

我成功插入一行(带有波斯名称)并在列表视图中显示;

> But when i select i have errors: String ROW3 = "SELECT * FROM category
> WHERE name=" + a; 
>Cursor cursor = db.rawQuery(ROW3, null);
>cursor.moveToFirst();
>Log.d("ghable vorod be for", "sa");
>for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext())
        {
            Log.d("ghable vorod be for1", "sa");
            cat_id=(cursor.getColumnIndex("id_category"));
            Log.d("ghable vorod be for2", "sa");
        }

但我在logcat中有这个错误:

sqlite 返回:错误代码 = 1,msg = 没有这样的列:بنزین

关闭虚拟机

线程以未捕获的异常退出 (group=0x40015560) E/AndroidRuntime(28713): FATAL EXCEPTION: main

android.database.sqlite.SQLiteException:没有这样的列:بنزین:,编译时:SELECT * FROM category WHERE name=بنزین

在 android.app.ActivityThread.main(ActivityThread.java:3683) 09-30 15:28:17.358: E/AndroidRuntime(28713): 在 java.lang.reflect.Method.invokeNative(Native Method) 09-30 15: 28:17.358: E/AndroidRuntime(28713): 在 java.lang.reflect.Method.invoke(Method.java:507) 09-30 15:28:17.358: E/AndroidRuntime(28713): 在 com.android.internal .os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 09-30 15:28:17.358: E/AndroidRuntime(28713): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 09-30 15:28:17.358: E/AndroidRuntime(28713): at dalvik.system.NativeStart.main(Native Method) 09-30 15:33:17.468: I/Process(28713): 发送信号。PID:28713 SIG:9 invokeNative(本机方法)09-30 15:28:17.358:E/AndroidRuntime(28713):在 java.lang.reflect.Method.invoke(Method.java:507)09-30 15:28:17.358:E/AndroidRuntime (28713): 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 09-30 15:28:17.358: E/AndroidRuntime(28713): 在 com.android.internal.os。 ZygoteInit.main(ZygoteInit.java:597) 09-30 15:28:17.358: E/AndroidRuntime(28713): at dalvik.system.NativeStart.main(Native Method) 09-30 15:33:17.468: I/Process (28713):发送信号。PID:28713 SIG:9 invokeNative(本机方法)09-30 15:28:17.358:E/AndroidRuntime(28713):在 java.lang.reflect.Method.invoke(Method.java:507)09-30 15:28:17.358:E/AndroidRuntime (28713): 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 09-30 15:28:17.358: E/AndroidRuntime(28713): 在 com.android.internal.os。 ZygoteInit.main(ZygoteInit.java:597) 09-30 15:28:17.358: E/AndroidRuntime(28713): at dalvik.system.NativeStart.main(Native Method) 09-30 15:33:17.468: I/Process (28713):发送信号。PID:28713 SIG:9 internal.os.ZygoteInit.main(ZygoteInit.java:597) 09-30 15:28:17.358: E/AndroidRuntime(28713): at dalvik.system.NativeStart.main(Native Method) 09-30 15:33:17.468 : I/Process(28713): 发送信号。PID:28713 SIG:9 internal.os.ZygoteInit.main(ZygoteInit.java:597) 09-30 15:28:17.358: E/AndroidRuntime(28713): at dalvik.system.NativeStart.main(Native Method) 09-30 15:33:17.468 : I/Process(28713): 发送信号。PID:28713 SIG:9

4

2 回答 2

3

您根本不应该将值直接包含在 SQL 中。相反,使用参数化 SQL,例如:

Cursor cursor = db.rawQuery("SELECT * FROM category WHERE name=?",
                            new String[] { a });

那样:

  • 您无需担心应该如何表示非 ASCII
  • 您无需担心转义数据以避免SQL 注入攻击
  • 您的 SQL 更易于阅读,无需所有字符串连接

(在普通的 JDBC 中,您可以为除 String 之外的其他数据类型设置参数,也可以避免转换问题 - 看起来这在这里不太可用,但这是参数化 SQL 的一个共同好处。)

于 2013-10-25T15:45:10.650 回答
2

对于数据库中的普通字符串值插入,我们有一种方法,它'在开始和结束处附加字符,并且所有出现的'字符都替换为''.

public String FormatDBString(String StringToFormat)
{           
   if (StringToFormat == null || StringToFormat.equals(""))
    {
        return "'"+ "" + "'";
    }
    else
        return "'" + StringToFormat.replace("'", "''") + "'";
}

然后您可以将此功能用作

String ROW3 = "SELECT * FROM category WHERE name= " + FormatDBString(a)

此功能提供了可用性,因为我们必须编写如此多的 SQL 并且错误的机会,SQL 注入等也被最小化。

于 2013-10-25T15:57:02.183 回答