【发布时间】:2014-02-02 14:39:58
【问题描述】:
- (id)init {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *databasePath = [documentsDirectory stringByAppendingPathComponent:@"idataBase.sqlite3"];
NSLog(@"Doc path: %@",databasePath);
bool databaseAlreadyExists = [[NSFileManager defaultManager] fileExistsAtPath:databasePath];
if (!databaseAlreadyExists){
NSString *databasePathFromApp = [[NSBundle mainBundle] pathForResource:@"idataBase" ofType:@"sqlite3"];
NSLog(@"Main bundle path: %@",databasePathFromApp);
[[NSFileManager defaultManager] copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
}
if (sqlite3_open([databasePath UTF8String], &_database) == SQLITE_OK){
NSLog(@"Database opened");
}dd
return self;
}
-(void) setData:(NSDictionary *)data{
NSLog(@"In Data %@",data);
NSString *hostAddress = [data objectForKey:@"hostAddress"];
NSString *userName = [data objectForKey:@"userName"];
NSString *passKey = [data objectForKey:@"passKey"];
NSString *listName = [data objectForKey:@"listName"];
NSString *q = [NSString stringWithFormat:@"INSERT INTO user_info (host_name,user_name,password,text_name) VALUES (\"%@\", \"%@\", \"%@\", \"%@\")",hostAddress,userName,passKey,listName];
NSLog(@"%@",q);
sqlite3_stmt *statement = NULL;
const char *insertQuery = [q UTF8String];
sqlite3_prepare_v2(_database, insertQuery, -1, &statement, NULL);
if(sqlite3_step(statement) == SQLITE_OK){
NSLog(@"Data Inserted");
}
sqlite3_finalize(statement);
sqlite3_close(_database);
}
我正在使用上面的代码插入数据。数据库连接在 init 方法中打开。但我无法在数据库中插入数据。 sqlite3_step(statement) 从不返回 SQLITE_OK。
【问题讨论】:
-
第一个主要问题 - 您正在使用
stringWithFormat构建查询。不要那样做。正确使用sqlite3_bind_xxx将值绑定到您的查询中。并在出现故障时使用sqlite3_errmsg记录错误。并检查对sqlite3_prepare_v2的调用结果。我在您关于删除数据的最后一个问题中提到了大部分内容。您需要进行适当的错误检查。 -
@rmaddy 谢谢。它显示了一些错误“库例程调用乱序”
-
您没有解决我在其他问题中指出的其他问题。您对
sqlite3_open和sqlite3_close的呼叫仍然不平衡。此类是否有其他适用于数据库的方法?确保所有方法正确调用prepare、step、finalize。并将close放入dealloc方法中。 -
并考虑使用 FMDB 代替原始 sqlite。
-
rmaddy 说 FMDB 值得考虑是对的,因为它极大地简化了您的流程。值得注意的是,如果使用 C 接口,在 SQL 中使用
?占位符(这非常重要)需要大量的sqlite3_bind_xxx调用,但 FMDB 消除了这个过程的痛苦。