使用NSString / parameters进入SQLite语句iOS

时间:2014-02-18 18:23:56

标签: ios objective-c sqlite

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

2 个答案:

答案 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)

我将尝试解释您的代码发生了什么以及如何改进代码以避免崩溃。我完全同意绑定参数的使用,这个答案只是因为它代表了如何修复崩溃的答案,并且可能会帮助那些没有时间切换到绑定语句的人。

以下是发生的事情:

  1. v失败,因为您的字符串包含sqlite3_prepare_v2()被追究的
  2. ,因此您的查询字符串无效
  3. 由于上述原因,"statement或包含垃圾值
  4. NULL崩溃,因为无效指针作为参数传递。
  5. 以下是修复:

    1. 通过将sqlite3_step()替换为"来转义所有字符串,这将生成有效查询;如果您在查询中使用\",则必须按'替换'
    2. 电子邮件示例:

      \'
      1. 即使您确定查询正确,在使用任何其他NSString *escapedEmail = [_emailValue stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]; 来电中的语句之前,仍然必须检查sqlite3_prepare_v2()的结果。
      2. 作为一般说明,在处理C API时需要非常防御性地进行编码,因为如果您忘记检查sqlite指针,C不会原谅您。 Objective-C更柔和,因为它允许您向NULL对象发送消息。