我正在与这个数据库作斗争,我有一个奇怪的问题...如果我尝试作为项目名称插入一个单词,一切正常,但如果单词是2或更多,它会失败!
这是代码的一部分:
NSString *insertStatementsNS =
[NSString stringWithFormat: @"insert into \"shoppinglist\"
(item, price, groupid, dateadded) values (\"%@\", %@, %d, DATETIME('NOW'))",
name_field, price_field, [groupPicker selectedRowInComponent:0]];
我猜问题出在 - > \“%@ \”< - 但我不知道如何解决它。
有人能帮助我吗?
我按照上面的步骤操作,但出了点问题,现在我在这里遇到了这个新错误:
NSString *itemValue = [[NSString alloc] initWithUTF8String: (char*) sqlite3_column_text(dbps, 1)];
并且程序在启动时停止...它无法再从DB中读取......发生了什么?
#
好的,感谢朋友...我们只是重置模拟器内存。 我们也解决了这个问题...以另一种方式工作。
我没有使用变量“name_field”,而是使用了“itemNameField.text”(直接到源代码......),并且出于某种原因它可以正常工作!
答案 0 :(得分:2)
您应该避免直接为sql语句中的列赋值。相反,您应该使用prepared statement
和bind
值。
sqlite3_stmt *stmt = nil;
NSString *sqlStr = @"insert into shoppinglist(item, price, groupid, dateadded)
values (?, ?, ?, DATETIME('NOW'))";
char *sql = (char *) [sqlStr UTF8String];
if (sqlite3_prepare_v2(DB, sql, -1, &stmt, NULL) != SQLITE_OK) {
NSAssert1(0, @"Error Preparing Statement: %s", sqlite3_errmsg(DB));
}
sqlite3_bind_text(stmt, 1, name_field, -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 2, price_field, -1, SQLITE_TRANSIENT);
sqlite3_bind_int(stmt, 3, [groupPicker selectedRowInComponent:0]);
...
使用预准备语句总是安全的,如果您直接替换字符串值,并且字符串值包含双引号("
或"
)等特殊字符,那么会有不良结果执行sql。但是,如果您使用预准备语句,则不必担心绑定值的实际内容。这些值将安全地添加到db。
答案 1 :(得分:1)
只需使用'%@'
即可NSString *insertStatementsNS =
[NSString stringWithFormat: @"insert into \"shoppinglist\"
(item, price, groupid, dateadded) values ('%@', %@, %d, DATETIME('NOW'))",
name_field, price_field, [groupPicker selectedRowInComponent:0]];