我正在学习如何在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没有这样的列,但有它与硬编码字符串一起使用
我出错的任何想法?
任何帮助表示赞赏
标记
答案 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执行。
最后几行只是清理。