将json数据保存到iOS中的sqlite数据库中

将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数组传递给此方法只节约了第一个数组对象的值。即只有第一个字典值被保存。请告诉我我做错了什么。

+0

请更新您的问题与您的问题相关的代码。你试过什么了?您问题中的代码与您的问题无关。 – rmaddy

+0

不相关,但你为什么要这样构建CREATE语句?为什么它不是单个字符串?至少使用'NSMutableString'来逐个构建它。 – rmaddy

+0

我已更新我的问题。请检查一下。 –

你首要的问题是你误访问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; 
} 
  1. 没有必要try/catch。只要做适当的错误检查。
  2. 使用NSMutableString逐个构建一个字符串。
  3. 只有在成功准备好声明后才能完成声明。
  4. 确保在打开数据库时关闭数据库。
  5. 使用现代语法来访问字典和数组中的值。阅读和输入更容易。
  6. 尽可能使用现代循环。
  7. 使用空格。它使代码更易于阅读。
  8. 给你所有的方法参数一个名字。

但是你的SQLite代码实际上比大多数帖子都好。实际上,您使用sqlite_bind_xxx将值绑定到您的查询。很少有人这样做。

+0

感谢您的帮助和提示。 –

在你的代码中你抓住了值,你用敛行数据:

NSDictionary *rowData=[data objectAtIndex:0]; 

我怀疑你的意思是:

NSDictionary *rowData=[data objectAtIndex:i]; 
+0

感谢您的建议@Rob –

+0

现在我想再添加一列到表中。在我的项目中,我有一个表格视图,其中我显示所有从sqlite数据库提取的数据。但现在我想保存tableView单元格的值。例如,如果我选择第一个单元格,那么它应该将它保存在数据库的新列中,并说'情绪1选择和保存',如果我选择第三个单元格,它应该将其保存在数据库新列并说'情绪3选择和保存',等等......任何人都可以帮我解决这个问题@Rob –

+0

我不是很遵循你问的问题。我建议你在Stack Overflow上发布新的问题,向我们展示你的尝试,当你尝试时发生了什么,并描述你想要发生的事情。但是上面的评论中没有足够的内容来诊断正在发生的事情。 – Rob