我的代码如下。我的值_emailVaue
_passwordValue
和_nameValue
取自我的应用中的UITextFields
。我的印象是,在我的SQLite代码中将这些值传递给参数将允许我在这些值中使用特殊字符,例如双引号(“),但是,如果我将它们放入,SQLite崩溃。有什么我我做错了吗?
我知道最好使用像FMDB这样的东西,但我希望有更快的解决办法让我通过即将到来的演示。
感谢任何帮助,谢谢!
if (sqlite3_open(dbpath, &_contactDB) == SQLITE_OK)
{
NSString *insertSQL = [NSString stringWithFormat:
@"INSERT INTO CONTACTS (email, password, name) VALUES (\"%@\", \"%@\", \"%@\")",
_emailValue, _passwordValue, _nameValue];
NSLog(insertSQL);
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(_contactDB, insert_stmt,
-1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
} else {
}
sqlite3_finalize(statement);
sqlite3_close(_contactDB);
}
答案 0 :(得分:1)
我希望如果它似乎有用,可以回答我自己的问题。希望有人会发现它很有用。非常感谢任何关于我可能出错的反馈。
sqlite3_stmt *statement;
const char *dbpath = [_databasePath UTF8String];
const char *insertSQL;
if (sqlite3_open(dbpath, &_contactDB) == SQLITE_OK)
{
insertSQL = "INSERT INTO CONTACTS (email, password, name) VALUES (?, ?, ?)";
if(sqlite3_prepare_v2(_contactDB, insertSQL, -1, &statement, NULL) == SQLITE_OK)
{
sqlite3_bind_text(statement, 1, [_emailValue UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(statement, 2, [_passwordValue UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(statement, 3, [_nameValue UTF8String], -1, SQLITE_TRANSIENT);
}
if (sqlite3_step(statement) == SQLITE_DONE)
{
//worked
} else {
//didn't work
}
sqlite3_finalize(statement);
sqlite3_close(_contactDB);
}
答案 1 :(得分:0)
我将尝试解释您的代码发生了什么以及如何改进代码以避免崩溃。我完全同意绑定参数的使用,这个答案只是因为它代表了如何修复崩溃的答案,并且可能会帮助那些没有时间切换到绑定语句的人。
以下是发生的事情:
v
失败,因为您的字符串包含sqlite3_prepare_v2()
被追究的"
是statement
或包含垃圾值NULL
崩溃,因为无效指针作为参数传递。以下是修复:
sqlite3_step()
替换为"
来转义所有字符串,这将生成有效查询;如果您在查询中使用\"
,则必须按'
替换'
电子邮件示例:
\'
NSString *escapedEmail = [_emailValue stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""];
来电中的语句之前,仍然必须检查sqlite3_prepare_v2()
的结果。作为一般说明,在处理C API时需要非常防御性地进行编码,因为如果您忘记检查sqlite
指针,C不会原谅您。 Objective-C更柔和,因为它允许您向NULL
对象发送消息。