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

时间:2016-05-17 15:53:13

标签: ios arrays json sqlite relational-database

我的问题是如何将获取的JSON数组数据插入sqlite数据库。 我已经获取了JSON数据,这是一个字典数组。

我保存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 *insertSQL=@"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数组传递给此方法时,它只保存第一个数组对象的值。即只保存第一个字典值。请告诉我我做错了什么。

2 个答案:

答案 0 :(得分:0)

在您抓取值的代码中,您将使用以下内容获取行数据:

NSDictionary *rowData=[data objectAtIndex:0];

我怀疑你的意思是:

NSDictionary *rowData=[data objectAtIndex:i];

答案 1 :(得分: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. 为您的所有方法参数命名。
  9. 但是你的SQLite代码实际上比这里的大多数帖子更好。实际上,您使用sqlite_bind_xxx将值绑定到查询中。很少有人这样做。