SQLite 中的语法错误(插入语句)

Posted

技术标签:

【中文标题】SQLite 中的语法错误(插入语句)【英文标题】:Syntax Error in SQLite (Insert Statement) 【发布时间】:2016-06-10 18:50:46 【问题描述】:

我正在使用 android 的 SQLite 存储选项来存储一本书的一些参考资料。表已创建,但执行 Insert 语句时出错。

这是查询字符串:

writeableDatabase.execSQL("INSERT INTO " + BookSave.TABLE_NAME +
                                " VALUES( " + book.getTitle().toString() +
                                "," + book.getAuthor().toString() + ","
                                + book.getPathOfCover().toString() + " );");

这是日志:

near "Devices": syntax error
02-27 19:21:04.555 23973-24058/dreamnyc.myapplication E/AndroidRuntime: FATAL EXCEPTION: Thread-2698
02-27 19:21:04.555 23973-24058/dreamnyc.myapplication E/AndroidRuntime: Process: dreamnyc.myapplication, PID: 23973
02-27 19:21:04.555 23973-24058/dreamnyc.myapplication E/AndroidRuntime: android.database.sqlite.SQLiteException: near "Devices": syntax error (code 1): , while compiling: INSERT INTO book VALUES( Electronic Devices & Circuits,Jacob Millman & Christos C. Halkias,/storage/emulated/0/Android/data/dreamnyc.myapplication/files/MillmanHalkias-ElectronicDevicesCircuits/OEBPS/images/leaf-image0000.jpg );
02-27 19:21:04.555 23973-24058/dreamnyc.myapplication E/AndroidRuntime:     at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
02-27 19:21:04.555 23973-24058/dreamnyc.myapplication E/AndroidRuntime:     at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:891)
02-27 19:21:04.555 23973-24058/dreamnyc.myapplication E/AndroidRuntime:     at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:502)
02-27 19:21:04.555 23973-24058/dreamnyc.myapplication E/AndroidRuntime:     at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
02-27 19:21:04.555 23973-24058/dreamnyc.myapplication E/AndroidRuntime:     at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
02-27 19:21:04.555 23973-24058/dreamnyc.myapplication E/AndroidRuntime:     at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
02-27 19:21:04.555 23973-24058/dreamnyc.myapplication E/AndroidRuntime:     at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1674)
02-27 19:21:04.555 23973-24058/dreamnyc.myapplication E/AndroidRuntime:     at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1605)
02-27 19:21:04.555 23973-24058/dreamnyc.myapplication E/AndroidRuntime:     at dreamnyc.myapplication.MainActivity$2.run(MainActivity.java:189)
02-27 19:21:04.555 23973-24058/dreamnyc.myapplication E/AndroidRuntime:     at java.lang.Thread.run(Thread.java:818)

【问题讨论】:

为了避免 SQL 注入使用参数绑定。无论如何,您的查询没有 ' 围绕字符串文字。 INSERT INTO book VALUES( Electronic Devices &amp; Circuits,Jacob Millman &amp; Christos C. Halkias,/storage/emulated/0/Android/data/dreamnyc.myapplication/files/MillmanHalkias-ElectronicDevicesCircuits/OEBPS/images/leaf-image0000.jpg 我该怎么做?参数绑定是什么意思? How do I use prepared statements in SQlite in Android? 绑定参数是标记(?),替换为字符串数组值。 不要键入带有字符串连接的原始 sql 字符串。像这样使用insert 方法。 ***.com/a/6251275/2308683 【参考方案1】:

问题是,如果值是 varchar 类型,则需要在值周围加上引号:

writeableDatabase.execSQL("INSERT INTO " + BookSave.TABLE_NAME +
                                " VALUES( '" + book.getTitle().toString() +"'," 
                                +"'"+ book.getAuthor().toString() + "',"
                                +"'"+ book.getPathOfCover().toString() + "');");

真正的问题是您应该使用参数化查询来避免这些类型的错误,同时还要防止 sql 注入。

例如:

ContentValues values = new ContentValues();
values.put(KEY_TITLE, book.getTitle().toString());
values.put(KEY_AUTHOR, book.getAuthor().toString());
values.put(KEY_PATH_COVER, book.getPathOfCover().toString());
writeableDatabase.insert(TABLE_NAME, null, values);

KEY_ 是字符串形式的列名

【讨论】:

以上是关于SQLite 中的语法错误(插入语句)的主要内容,如果未能解决你的问题,请参考以下文章

插入语句中的 OleDbException 语法错误

Sqlite3.c 中的 For-loop 语法错误

SQLite - 从 myTable 插入到 myTable 中选择计数 (*) 其中 Date = 'mydate' 语法错误

插入语句 C# OleDb 中的语法错误

“COLUMN_NAME”附近:SQLite 中的语法错误(代码 1)

INSERT INTO 语句中的语法错误(将多条记录从 Gridview 插入到 Access)