有一些简单的准则,坦率地说,您的代码根本不遵循任何准则。
对于每个成功的调用sqlite3_open
你必须打电话sqlite3_close
.
对于每个成功的调用sqlite3_prepare_v2
你必须打电话sqlite3_finalize
。或者,您可以在两者之间致电sqlite3_reset
如果您重复使用准备好的语句,则可以使用零次或多次。
您应该始终检查调用的结果sqlite3_open
and sqlite3_prepare_v2
。如果他们失败了,你应该使用sqlite3_errmsg
记录问题所在。
不要使用构建查询字符串stringWithFormat
。相反,使用对各种适当的调用将值正确绑定到查询sqlite3_bind_xxx
功能。
您发布的代码违反了所有这些。在很多情况下,您都没有关闭数据库或完成准备好的语句。并且您错误地构建了查询stringWithFormat:
.
这是您的代码全部已修复。请注意,我假设您插入的所有值都是字符串。针对任何非字符串值进行相应调整。
- (BOOL) saveData:(User *)user
{
BOOL result = NO;
if([self getUserData:user.email] != nil)
{
[self updateUserData:user];
result = YES;
}
else
{
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
const char *insert_stmt = "insert into users(userid,name,email,password,address,age,gender,phone,qualification,role,createddate,apiKey,priorityid,usertype) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
if (sqlite3_prepare_v2(database, insert_stmt,-1, &statement, NULL) == SQLITE_OK) {
sqlite3_bind_text(stmt, 1, [user.userid UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 2, [user.name UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 3, [user.email UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 4, [user.password UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 5, [user.address UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 6, [user.age UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 7, [user.gender UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 8, [user.phone UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 9, [user.qualification UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 10, [user.role UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 11, [user.createddate UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 12, [user.api_key UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 13, [user.priority_id UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 14, [user.user_type UTF8String], -1, SQLITE_TRANSIENT);
if (sqlite3_step(statement) == SQLITE_DONE)
{
result = YES;
}
sqlite3_finalize(statement);
}
else
{
NSLog(@"Unable to prepare statement: %s",sqlite3_errmsg(database));
}
sqlite3_close(database);
}
else
{
NSLog(@"Unable to open database: %s",sqlite3_errmsg(database));
}
}
return result;
}
根据新编辑进行更新:
就像您的原始代码一样,您违反了一些规则。您更新的代码并不完全遵循我在上面的答案中给出的模式。
现在的主要问题是您打开数据库,但仅在两个可能的代码路径之一下关闭它。如果inspMap != nil
你永远不会关闭数据库。
您确实应该重构代码,以便仅在以下情况下打开数据库:inspMap
is nil
。我在原始答案中做了与您的原始代码类似的操作。