2012-06-06 9 views
5

Estoy tratando de iterar a través de un tipo de tabla maestra de detalles y me gustaría llenar las estructuras maestra/de detalles a medida que avanzo. Al parecer, cuando los conjuntos de resultados I nidos que tienen una mala excepción acceso:sqlite3 y fmdb anidados FMResultSet es posible?

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]; 

En los RS2 (segundo conjunto de resultados) consigo el EXEC_BAD_ACCESS dentro de la clase FMDatabase.

¿Es esto una restricción de sqlite3/fmdb o estoy haciendo algo mal aquí?

+0

No veo nada incorrecto en su código, excepto un pequeño * nil * en la segunda definición de la consulta. Debe reducir el problema investigando qué causa exactamente la excepción. Una forma de hacerlo es ir al navegador de puntos de interrupción y colocar el punto de interrupción en todas las excepciones presionando el pequeño botón + en la parte inferior izquierda. Esto debería detener la ejecución en la línea exacta que causa la excepción. – lawicko

+0

Sí, estaba haciendo eso, pero me tomó un tiempo para entender lo 'int' ya que el error era un poco engañoso (de aquellos que provienen del mundo de Java como yo) ... De todos modos, ¡gracias por la respuesta! –

Respuesta

2

Acabo de encontrar lo que hice mal. Estaba pasando un int como parte de la segunda consulta. Tuve que convertirlo a 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]; 

Eso quiere decir que, sí, sqlite3/FMDB hace apoyar las consultas anidadas! :-)

0

estoy usando FMDB y Sqlite3 así, y me encuentro con consultas anidadas funcionan:

(No estoy afirmando la clave de código de abajo está bien, no importa el formato, por favor)

Tanto maestra y detalle tablas tienen una columna llamada '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 
    } 
} 

Esta fue una agradable sorpresa, en realidad. Esperaba a medias tener que consultar primero todos los registros maestros y luego recorrerlos en la memoria de la aplicación para recoger los detalles de SQlite3. Pero la construcción anterior funciona bien.

Cuestiones relacionadas