iOS sqlite插入带变量的语句

时间:2016-03-31 20:55:45

标签: ios sqlite insert

我正在学习如何在IOS中使用sqlite

我使用以下内容将记录插入表

 int DBID =  [_db  ExecuteINSERT:@"INSERT INTO LOG(NAME , COMPANY , CATEGORY)   VALUES('txt1','txt2','txt3')"];

这很好用并将三个字符串添加到一行

我想为字符串变量交换硬编码字符串,但可以解决该怎么做。我试过了

NSString* myString1 = @"String1";
NSString* myString2 = @"String2";
NSString* myString3 = @"String3";
int DBID = _db  ExecuteINSERT:@"INSERT INTO LOG(NAME , COMPANY,     CATEGORY) VALUES(myString1, myString2, myString3)"];

但是我得到一个sqlite错误1没有这样的列,但有它与硬编码字符串一起使用

我出错的任何想法?

任何帮助表示赞赏

标记

1 个答案:

答案 0 :(得分:0)

你要声明相同的字符串3次,但我会认为这只是你问题中的一个错字,而你真正拥有(或者至少意味着)的是:

NSString* string1 = @"String1";
NSString* string2 = @"String2";
NSString* string3 = @"String3";

您的下一个问题是您已将变量名称作为文字字符串包含在"中 - 这意味着SQL语句将包含“string1”而不是string1的值,这就是您的意思后。

由于您正在使用SQLite的包装器,因此可以使用stringWithFormat创建insert语句,并将字符串变量的值替换为

NSString *sqlStatement=[NSString stringWithFormat:@"INSERT INTO LOG(NAME, COMPANY,CATEGORY) values (\"%@\",\"%@\",\"%@\")",string1,string2,string3];
int DBID = [_db  ExecuteINSERT:sqlStatement];

值得注意的是,这是不安全的,因为您无法防范从用户输入获取值的SQL injection。这可能不是移动设备的问题;用户可以做的最糟糕的事情是影响他们自己的数据库。

如果您不使用包装器,那么技术上正确的方法是使用sqlite3_prepare_v2 -

sqlite3_stmt *statement;
NSString *insertSQL = @"INSERT INTO LOG(NAME, COMPANY,CATEGORY) values (?,?,?)"; 
const char *insert_stmt = [insertSQL UTF8String];
if (sqlite3_prepare_v2(_db, insert_stmt,-1, &statement, NULL)!= SQLITE_OK) {
    // LOG THE ERROR
    NSLog(@"Error: failed to perpare statement with message '%s'.", sqlite3_errmsg(_db));
}
else {
    // Bind values to the statement
    sqlite3_bind_text(statement,1,[string1 UTF8String],-1,SQLITE_TRANSIENT);
    sqlite3_bind_text(statement,2,[string2 UTF8String],-1,SQLITE_TRANSIENT);
    sqlite3_bind_text(statement,3,[string3 UTF8String],-1,SQLITE_TRANSIENT);
    double retValue = sqlite3_step(statement);
    if (retValue == SQLITE_DONE) {
            NSLog(@"Insert successful");
    }
    sqlite3_reset(statement);
    sqlite3_finalize(statement);
}

第二个代码块创建一个包含三个占位符(?,?,?)的语句,然后将字符串替换为sqlite3_bind_text的占位符。最后,该语句使用sqlite3_step执行。

最后几行只是清理。