2016-05-17 2 views
0

Мой вопрос заключается в том, как вставить полученные данные массива JSON в базу данных sqlite. Я получил данные JSON, которые представляют собой набор словарей.сохранение данных json в базе данных sqlite в iOS

Мой код для сохранения 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

Я обновил свой вопрос. Пожалуйста, проверь это. –

ответ

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

спасибо за помощь и советы. –

0

В вашем коде, где вы захватывая ценности, вы захватывая данные строки с:

NSDictionary *rowData=[data objectAtIndex:0]; 

Я подозреваю, что вы имеете в виду:

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

спасибо за предложение @Rob –

+0

Теперь я хочу добавить еще один столбец в таблицу. В моем проекте у меня есть табличный вид, в котором я показываю все извлеченные данные из базы данных sqlite. Но теперь я хочу сохранить значение ячейки tableView. Например, если я выбираю первую ячейку, тогда она должна сохранить ее в базах данных нового столбца и сказать «настроение 1 выбрано и сохранено», если я выберу третью ячейку, он должен сохранить ее в базах данных нового столбца и сказать «выбранные и сохраненные настроения 3», и так далее ... Может ли кто-нибудь помочь мне с этой проблемой? @Rob –

+0

Я не совсем понимаю, что вы просите. Я предлагаю вам опубликовать новый вопрос о переполнении стека, показывая нам, что вы пробовали, что произошло, когда вы это пробовали, и опишите, что вы хотели. Но в вашем комментарии выше недостаточно, чтобы я мог диагностировать, что происходит. – Rob

Смежные вопросы