2016-05-17 181 views
0

我的問題是如何將獲取的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

我已更新我的問題。請檢查一下。 –

回答

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

我不是很遵循你問的問題。我建議你在Stack Overflow上發佈新的問題,向我們展示你的嘗試,當你嘗試時發生了什麼,並描述你想要發生的事情。但是上面的評論中沒有足夠的內容來診斷正在發生的事情。 – Rob