5

マスター詳細の種類のテーブルを反復処理しようとしていますが、マスター/詳細構造にデータを入力したいと思います。どうやら、結果セットをネストすると、BADAccess例外が発生します。

FMDatabase *db = self.database;
[db open];
db.traceExecution = YES;
db.logsErrors = YES;
FMResultSet *rs = [db executeQuery:@"select group_id, label from main.preference_group order by group_id"];
while ([rs next])
{
    PreferenceGroup *pg = [[PreferenceGroup alloc] init];
    pg.group_id = [rs intForColumn:@"group_id"];
    pg.label = [rs stringForColumn:@"label"];
    pg.translatedLabel = NSLocalizedString(pg.label, nil);
    NSMutableArray * prefs = [[NSMutableArray alloc] init];
    [prefGroups addObject:prefs];
    FMResultSet *rs2 = [db executeQuery:@"select pref_id, label, value from main.preference where group_id = ? order by pref_id", pg.group_id, nil];
        while ([rs2 next])
        {
            Preference * pref = [[Preference alloc] init];
            pref.group_id = pg.group_id;
            pref.pref_id = [rs2 intForColumn:@"pref_id"];
            pref.label = [rs2 stringForColumn:@"label"];
            pref.value = [rs2 stringForColumn:@"value"];
            pref.translatedLabel = NSLocalizedString(pref.value, nil);
            [prefs addObject:pref];
        }
        [rs2 close];
    }
    [rs close];
    [db close];

rs2(2番目の結果セット)で、FMDatabaseクラス内のEXEC_BAD_ACCESSを取得します。

これはsqlite3/fmdbの制限ですか、それともここで何か間違ったことをしていますか?

4

2 に答える 2

2

私は自分が間違ったことを見つけました。2番目のクエリの一部としてintを渡していました。NSNumberに変換する必要がありました:

            FMResultSet *rs2 = [db executeQuery:@"select pref_id, label, value from main.preference where group_id = ? order by pref_id", [NSNumber numberWithInt:pg.group_id], nil];

つまり、はい、sqlite3 / fmdbはネストされたクエリをサポートします!:-)

于 2012-06-07T11:45:01.770 に答える
0

FMDBとSQLITE3も使用していますが、ネストされたクエリが機能することがわかりました。

(以下のコードヒントが良いとは言いません。フォーマットは気にしないでください)

マスターテーブルと詳細テーブルの両方に、「id」という列があります

FMResultSet *rso = [database executeQuery:@"select * from master order by id"];
while ([rso next])
{
    NSInteger masterId = [rso intForColumn:@"id"];
    NSString *q3 = [[NSString alloc] initWithFormat:
               @"select * from detail where masterid = %d order by id", masterId, nil ];

    FMResultSet *rsa = [database executeQuery:q3 ];

    while ([rsa next])
    {
        NSInteger detailId   = [rsa intForColumn:@"id"];
        //
        // here do something with masterId and detailId 
    }
}

実際、これは嬉しい驚きでした。私は、最初にすべてのマスターレコードをクエリし、次にアプリメモリでそれらをループしてSQlite3から詳細を取得する必要があることを中途半端に予想していました。ただし、上記の構成は正常に機能します。

于 2013-03-20T19:28:29.843 に答える