2012-11-24 4 views
4

J'ai beaucoup de mal à trouver un exemple de travail sur Internet pour obtenir plusieurs valeurs d'une base de données SQlite en utilisant xcode et cocos2dx. Voici la requête SQL je:Requête SQlite - Comment récupérer plusieurs données de colonne?

char sql_query[100]; 
sprintf(sql_query, "SELECT * FROM SQList WHERE ColumnD BETWEEN %d AND %d ORDER BY RANDOM() LIMIT 1", MinColumnD, MaxColumnD); 

La requête elle-même semble fonctionner, le principal problème est de savoir comment puis-je obtenir les valeurs que je collectionne de « select * » dans un autre paramètre int ou char pour que je peut l'utiliser?

Quelques exemples I trouvé visée à l'aide d'un rappel à un struct ou mentionné sur l'utilisation de sqlite3_prepare_v2 et la méthode pas à pas.

Je suis incapable de trouver un exemple pour les deux méthodes, s'il vous plaît, aidez!

+0

Il y a un tutoriel mentionné [ici] (http: // stackoverflow .com/questions/10363028/comment-utiliser-sqlite-in-xcode-storyboard). – monex0

Répondre

5

Lorsque vous utilisez sqlite3_exec, vous devez convertir toutes les valeurs de chaînes, et vous devez utiliser le pointeur de rappel void * ou une variable globale pour renvoyer des données:

struct MyData { 
    string A; 
    int B, C; 
}; 

int exec_callback(void *ptr, int argc, char *argv[], char *names[]) 
{ 
    vector<MyData> *list = reinterpret_cast<vector<MyData> *>(ptr); 
    MyData d; 
    d.A = argv[0] ? argv[0] : ""; 
    d.B = atoi(argv[1]); 
    d.C = atoi(argv[2]); 
    list->push_back(d); 
    return 0; 
} 

void query_with_exec() 
{ 
    vector<MyData> list; 

    char *errmsg = NULL; 
    sqlite3_exec(db, "SELECT a, b, c FROM SQList /* WHERE ... */", 
       exec_callback, &list, &errmsg); 
    if (errmsg) { 
     printf("error: %s!\n", errmsg); 
     return; 
    } 

    // use list ... 
} 

Lorsque vous utilisez sqlite3_prepare*, vous ayiez e appeler sqlite3_step dans une boucle jusqu'à ce qu'il ne retourne pas SQLITE_ROW plus (quand vous attendez qu'un seul enregistrement, vous pouvez appeler une seule fois):

void query_with_step() 
{ 
    vector<MyData> list; 
    sqlite3_stmt *stmt; 

    int rc = sqlite3_prepare_v2(db, "SELECT a, b, c FROM SQList /* WHERE ... */", 
           -1, &stmt, NULL); 
    if (rc != SQLITE_OK) { 
     printf("error: %s!\n", sqlite3_errmsg(db)); 
     return; 
    } 

    for (;;) { 
     rc = sqlite3_step(stmt); 
     if (rc == SQLITE_DONE) 
      break; 
     if (rc != SQLITE_ROW) { 
      printf("error: %s!\n", sqlite3_errmsg(db)); 
      break; 
     } 

     MyData d; 
     const char *text = (const char *)sqlite3_column_text(stmt, 0); 
     d.A = text ? text : ""; 
     d.B = sqlite3_column_int(stmt, 1); 
     d.C = sqlite3_column_int(stmt, 2); 
     list.push_back(d); 
    } 

    sqlite3_finalize(stmt); 

    // use list ...  
} 
+0

Je pense que cette direction est plus sur ce dont j'ai besoin car j'utilise cocos2dx qui est en C++. Je suis toujours confronté à un problème ... dans la méthode sqlite3_exec, j'obtiens un EXC_BAD_ACCESS dans la liste de rappel-> push_back (d); section. Lorsque j'utilise la méthode prepare_v2, j'obtiens un EXC_BAD_ACCESS sur l'int rc = sqlite3_prepare_v2 (db, "SELECT un, b, c FROM SQList/* WHERE ..) Je suppose que cela a à voir avec la façon dont je déclare , mais un peu coincé ici – user1842318

+0

Works pour moi écrire un programme minimal * * qui ouvre juste la DB et appelle 'sqlite3_prepare_v2';.. ça plante trop –

+0

Grand Merci pour les conseils que je compris le problème maintenant?! C'était aussi simple que de ne pas allouer assez de mémoire pour le caractère sql_quer! – user1842318

0

obtenir les valeurs à l'aide « SELECT » requête et stocker votre personnage et int valeurs dans un Array.create un NSMutableArray et stocker les valeurs que vous obtiendrez de requête SELECT .Le code suivant vous aidera

-(int)find_putts_count:(int)holeno{ 
    sqlite3 *database; 
NSString *databasePath; 
NSMUtableArray *arr_tracking_details = [[NSMUtableArray alloc] init]; 
int putts = -1; 
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *documentsDir = [documentPaths objectAtIndex:0]; 
databasePath = [documentsDir stringByAppendingPathComponent:@"GolfElite.sqlite"]; 
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) 
{ 
    // Setup the SQL Statement and compile it for faster access 
    NSString *sqlStatement = nil; 
      sqlStatement = [NSString stringWithFormat:@"select Putts from Holes WHERE HoleNo == %d and ShotNo == %d and PlayerId == '%@'",holeno,1,[arr_players_id objectAtIndex:scorecard_player_no]]; 
    sqlite3_stmt *compiledStatement; 
    if(sqlite3_prepare_v2(database, [sqlStatement UTF8String], -1, &compiledStatement, NULL) == SQLITE_OK) 
    { 
     if(sqlite3_step(compiledStatement) == SQLITE_ROW) 
     { 
      [arr_tracking_details addObject:[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)]]; 
      [arr_tracking_details addObject:[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement,6)]]; 
      [arr_tracking_details addObject:[NSString stringWithFormat:@"%d",(int)sqlite3_column_int(compiledStatement, 4)]]; 

      putts = (int)sqlite3_column_int(compiledStatement, 0); 
     } 
    } 
    sqlite3_finalize(compiledStatement); 
} 
sqlite3_close(database); 
return putts; 
} 
Questions connexes