将json数据保存到iOS中的sqlite数据库中
我的问题是如何将获取的JSON数组数据插入到sqlite数据库中。 我已经提取了JSON数据,这是一个字典数组。将json数据保存到iOS中的sqlite数据库中
我的代码保存JSON结果如下:
-(BOOL) saveApiResults: (NSString *)tableName : (NSArray *)data
{
BOOL saveSuccess = NO;
@try {
const char *dbPath = [databasePath UTF8String];
if(sqlite3_open(dbPath,&database)==SQLITE_OK) {
sqlite3_exec(database, "BEGIN", 0, 0, 0);
//pass an array containing json dictionary to below line
NSDictionary *rowData=[data objectAtIndex:0];
NSArray *keyArray = [rowData allKeys];
NSLog(@"key array %@",keyArray);
NSString *[email protected]"INSERT INTO ";
insertSQL=[insertSQL stringByAppendingString:@"moodsdata"];
insertSQL=[insertSQL stringByAppendingString:@" VALUES("];
for(int j=0;j<[keyArray count];j++)
{
insertSQL=[insertSQL stringByAppendingString:@"?"];
if(j<[keyArray count]-1)
insertSQL=[insertSQL stringByAppendingString:@","];
}
insertSQL=[insertSQL stringByAppendingString:@");"];
NSLog(@"query : %@ ",insertSQL);
const char *sqlstatement = [insertSQL UTF8String];
sqlite3_stmt *compiledstatement;
if(sqlite3_prepare_v2(database,sqlstatement , -1, &compiledstatement, NULL)==SQLITE_OK) {
for (NSUInteger i = 0; i < [data count]; i++) {
NSDictionary *rowData=[data objectAtIndex:0];
for(int j=0;j<[keyArray count];j++) {
NSString *val = @"";
NSString *value=(NSString *)[rowData objectForKey:[keyArray objectAtIndex:j]];
if((value != nil) && (![value isEqual:[NSNull null]]))
val=[NSString stringWithFormat:@"%@",value];
NSLog(@"values %@",val);
sqlite3_bind_text(compiledstatement,j+1,[val UTF8String], -1, SQLITE_TRANSIENT);
}
if(sqlite3_step(compiledstatement) != SQLITE_DONE) {
NSLog(@"ERROR");
}
sqlite3_clear_bindings(compiledstatement);
sqlite3_reset(compiledstatement);
}
sqlite3_exec(database, "COMMIT", 0, 0, 0);
saveSuccess = YES;
NSLog(@"RESULTS SAVED SUCCESSFULLY!");
} else {
NSLog(@"StatemenT FAILED (%s)", sqlite3_errmsg(database));
}
sqlite3_finalize(compiledstatement);
} else {
NSLog(@"Statement FAILED (%s)", sqlite3_errmsg(database));
}
}
@catch (NSException *exception) {
NSLog(@"NSException : %@",exception.description);
}
@finally {
sqlite3_close(database);
}
return saveSuccess;
}
我的问题是,当我尝试JSON数组传递给此方法只节约了第一个数组对象的值。即只有第一个字典值被保存。请告诉我我做错了什么。
你首要的问题是你误访问data[0]
而不是data[i]
在您的循环中进行实际插入。
但是这个代码还有很多其他的小问题。这里是你的代码全部清理:
-(BOOL) saveApiResults:(NSString *)tableName data:(NSArray *)data
{
BOOL saveSuccess = NO;
const char *dbPath = [databasePath UTF8String];
if (sqlite3_open(dbPath,&database) == SQLITE_OK) {
sqlite3_exec(database, "BEGIN", 0, 0, 0);
//pass an array containing json dictionary to below line
NSDictionary *rowData = data[0];
NSArray *keyArray = [rowData allKeys];
NSLog(@"key array %@",keyArray);
NSMutableString *insertSQL = @"INSERT INTO moods data VALUES(";
for (NSInteger j = 0; j < [keyArray count]; j++)
{
if (j) {
[insertSQL appendString:@","];
}
[insertSQL appendString:@"?"];
}
[insertSQL appendString:@");"];
NSLog(@"query : %@ ",insertSQL);
const char *sqlstatement = [insertSQL UTF8String];
sqlite3_stmt *compiledstatement;
if (sqlite3_prepare_v2(database, sqlstatement, -1, &compiledstatement, NULL) == SQLITE_OK) {
for (NSDictionary *rowData in data) {
for (NSInteger j = 0; j < [keyArray count]; j++) {
NSString *val = @"";
NSString *value = rowData[keyArray[j];
if (value && ![value isEqual:[NSNull null]]) {
val = [NSString stringWithFormat:@"%@",value];
}
NSLog(@"values %@",val);
sqlite3_bind_text(compiled statement, j + 1, [val UTF8String], -1, SQLITE_TRANSIENT);
}
if (sqlite3_step(compiledstatement) != SQLITE_DONE) {
NSLog(@"ERROR");
}
sqlite3_reset(compiledstatement);
}
sqlite3_exec(database, "COMMIT", 0, 0, 0);
sqlite3_finalize(compiledstatement);
saveSuccess = YES;
NSLog(@"RESULTS SAVED SUCCESSFULLY!");
} else {
NSLog(@"StatemenTtFAILED (%s)", sqlite3_errmsg(database));
}
sqlite3_close(database);
} else {
NSLog(@"Statement FAILED (%s)", sqlite3_errmsg(database));
}
return saveSuccess;
}
- 没有必要
try/catch
。只要做适当的错误检查。 - 使用
NSMutableString
逐个构建一个字符串。 - 只有在成功准备好声明后才能完成声明。
- 确保在打开数据库时关闭数据库。
- 使用现代语法来访问字典和数组中的值。阅读和输入更容易。
- 尽可能使用现代循环。
- 使用空格。它使代码更易于阅读。
- 给你所有的方法参数一个名字。
但是你的SQLite代码实际上比大多数帖子都好。实际上,您使用sqlite_bind_xxx
将值绑定到您的查询。很少有人这样做。
感谢您的帮助和提示。 –
在你的代码中你抓住了值,你用敛行数据:
NSDictionary *rowData=[data objectAtIndex:0];
我怀疑你的意思是:
NSDictionary *rowData=[data objectAtIndex:i];
感谢您的建议@Rob –
现在我想再添加一列到表中。在我的项目中,我有一个表格视图,其中我显示所有从sqlite数据库提取的数据。但现在我想保存tableView单元格的值。例如,如果我选择第一个单元格,那么它应该将它保存在数据库的新列中,并说'情绪1选择和保存',如果我选择第三个单元格,它应该将其保存在数据库新列并说'情绪3选择和保存',等等......任何人都可以帮我解决这个问题@Rob –
我不是很遵循你问的问题。我建议你在Stack Overflow上发布新的问题,向我们展示你的尝试,当你尝试时发生了什么,并描述你想要发生的事情。但是上面的评论中没有足够的内容来诊断正在发生的事情。 – Rob
请更新您的问题与您的问题相关的代码。你试过什么了?您问题中的代码与您的问题无关。 – rmaddy
不相关,但你为什么要这样构建CREATE语句?为什么它不是单个字符串?至少使用'NSMutableString'来逐个构建它。 – rmaddy
我已更新我的问题。请检查一下。 –