Dev*_*000 12 sqlite objective-c ios
关于sqlite3的几个问题:
1.何时需要使用第一种方法而另一种方式?它们之间有区别吗?
sqlite3_prepare_v2(_contactDB, sql_stmt_getIdRecepteur, -1, &sqlStatement, NULL);
Run Code Online (Sandbox Code Playgroud)
和
if(sqlite3_prepare_v2(_contactDB, sql_stmt_getIdRecepteur, -1, &sqlStatement, NULL) == SQLITE_OK) {}
Run Code Online (Sandbox Code Playgroud)
2.什么时候最多指示使用'sqlite3_exec'而不是'sqlite3_prepare_v2'?
3.何时需要使用第一个,第二个或第三个:
while(sqlite3_step(sqlStatement) == SQLITE_ROW){}
if(sqlite3_step(sqlStatement) == SQLITE_ROW){}
if(sqlite3_step(sqlStatement) == SQLITE_DONE){}
Run Code Online (Sandbox Code Playgroud)
先感谢您
Rob*_*Rob 16
应始终检查SQLite函数的返回值,以确保它成功,因此最if
优选使用该语句.如果失败,可以调用sqlite3_errmsg()
检索错误的C字符串描述.
在任何情况下都可以使用sqlite3_prepare_v2
(而不是sqlite3_exec
):
一个是返回数据,因此将调用sqlite3_step
后跟一个或多个sqlite3_column_xxx
函数,为每行数据重复该过程; 要么
一个是将值绑定到?
SQL中的占位符sqlite3_bind_xxx
.
可以从上面推断出sqlite3_exec
只有在(a)SQL字符串没有参数时才会使用; (b)SQL不返回任何数据.这sqlite3_exec
更简单,但只应在这些特殊情况下使用.
请注意:关于?
占位符的这一点非常重要:应该避免手动构建SQL语句(例如,使用stringWithFormat
或Swift字符串插值),尤其是在插入的值包括最终用户输入时.例如,如果使用用户输入调用sqlite3_exec
with INSERT
,UPDATE
或者DELETE
使用用户输入创建的语句(例如,将用户提供的某些值插入数据库中),则可能会出现因未转义的引号和转义符号等引起的问题.一个也暴露于SQL注入攻击.
例如,如果commentString
由于用户输入而提供,则这是不可取的:
NSString *sql = [NSString stringWithFormat:@"INSERT INTO COMMENTS (COMMENT) VALUES ('%@')", commentString];
if (sqlite3_exec(database, [sql UTF8String], NULL, NULL, NULL) != SQLITE_OK) {
NSLog(@"Insert failure: %s", sqlite3_errmsg(database));
}
Run Code Online (Sandbox Code Playgroud)
相反,你应该:
const char *sql = "INSERT INTO COMMENTS (COMMENT) VALUES (?)";
if (sqlite3_prepare_v2(database, sql, -1, &statement, NULL) != SQLITE_OK) {
NSLog(@"Prepare failure: %s", sqlite3_errmsg(database));
return;
}
if (sqlite3_bind_text(statement, 1, [commentString UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK) {
NSLog(@"Bind 1 failure: %s", sqlite3_errmsg(database));
sqlite3_finalize(statement);
return;
}
if (sqlite3_step(statement) != SQLITE_DONE) {
NSLog(@"Step failure: %s", sqlite3_errmsg(database));
}
sqlite3_finalize(statement);
Run Code Online (Sandbox Code Playgroud)
注意,如果这个正确的实现感觉太多工作,你可以使用FMDB库,这将简化它:
if (![db executeUpdate:@"INSERT INTO COMMENTS (COMMENT) VALUES (?)", commentString]) {
NSLog(@"Insert failure: %@", [db lastErrorMessage]);
}
Run Code Online (Sandbox Code Playgroud)
这提供了严格的sqlite3_prepare_v2
方法,但sqlite3_exec
界面简单.
检索多行数据时,可以使用:
while(sqlite3_step(sqlStatement) == SQLITE_ROW) { ... }
Run Code Online (Sandbox Code Playgroud)
或者,更好的是,如果你想做正确的错误处理,你会做:
int rc;
while ((rc = sqlite3_step(sqlStatement)) == SQLITE_ROW) {
// process row here
}
if (rc != SQLITE_DONE) {
NSLog(@"Step failure: %s", sqlite3_errmsg(database));
}
Run Code Online (Sandbox Code Playgroud)
检索单行数据时,可以:
if (sqlite3_step(sqlStatement) != SQLITE_ROW) {
NSLog(@"Step failure: %s", sqlite3_errmsg(database));
}
Run Code Online (Sandbox Code Playgroud)
执行不会返回任何数据的SQL时,会:
if (sqlite3_step(sqlStatement) != SQLITE_DONE) {
NSLog(@"Step failure: %s", sqlite3_errmsg(database));
}
Run Code Online (Sandbox Code Playgroud)使用SQLite C界面时,您可以看到正确执行它需要一些工作.围绕这个名为FMDB的接口有一个瘦的Objective-C包装器,它不仅简化了与SQLite数据库的交互,而且更加强大.
归档时间: |
|
查看次数: |
12279 次 |
最近记录: |