使用NSString /参数进入SQLite语句iOS

我的代码如下。 我的值_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); } 

如果它似乎有用,我希望能回答我自己的问题。 希望有人会发现它很有用。 希望得到任何关于我可能出错的反馈。

 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. sqlite3_prepare_v2()失败,因为您的查询字符串无效,因为您的字符串包含"删除"
  2. 由于上述原因, statementNULL或包含垃圾值
  3. sqlite3_step()崩溃,因为无效指针作为参数传递。

这是修复:

  1. 转义所有字符串,通过替换" by \" ,这将生成一个有效的查询; 如果您在查询中使用' ,那么您必须用\'替换' \'

电子邮件示例:

 NSString *escapedEmail = [_emailValue stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]; 
  1. 即使你确定查询是正确的,在任何其他sqlite调用中使用该语句之前,仍然必须检查sqlite3_prepare_v2()的结果。

作为一般说明,在处理C API时需要非常防御性地进行编码,因为如果您忘记检查NULL指针,C不会原谅您。 Objective-C更柔和,因为它允许您向nil对象发送消息。