2010-10-01 4 views
0

C'est le code que j'utilise pour sélectionner des enregistrements de ma base de données. Je lie deux dates dans mon sql, cependant, quand j'arrive à sqlite3_step je reçois SQLITE_DONE où je devrais obtenir SQLITE_ROW. Il semble qu'il traite les liaisons plutôt que d'interroger les données.iPhone, sqlite3, comment transmettre des valeurs dans une instruction select?

Qu'est-ce que je fais mal?

NSString *startDateRangeString = @"2000-05-01"; 
NSString *endDateRangeString = @"2011-05-01"; 

sqlite3 *database; 
int result = sqlite3_open("mydb.db", &database); 
if(result != SQLITE_OK) 
{ 
    NSLog(@"Could not open db."); 
} 

const char *sql = "select pid from tmp where due >= '%@' and due < '%@' order by due, pid;"; 
sqlite3_stmt *statementTMP; 

int error_code = sqlite3_prepare_v2(database, sql, -1, &statementTMP, NULL); 
if(error_code == SQLITE_OK) { 

    sqlite3_bind_text(statementTMP, 1, [startDateRangeString UTF8String], -1, SQLITE_TRANSIENT); 
    sqlite3_bind_text(statementTMP, 2, [endDateRangeString UTF8String], -1, SQLITE_TRANSIENT); 

    int step_error_code = sqlite3_step(statementTMP); 

    while(sqlite3_step(statementTMP) == SQLITE_ROW) // I get 101 aka SQLITE_DONE 
    { 
     NSLog(@"Found!!"); 
    } 
} 
sqlite3_finalize(statementTMP); 
sqlite3_close(database); 

Répondre

1
char *statementTMP = "select pid from tmp where due >= '?1' and due < '?2' order by due, pid"; 
.... 
    sqlite3_bind_text(statementTMP, 1, [startDateRangeString UTF8String], -1, SQLITE_TRANSIENT); 
    sqlite3_bind_text(statementTMP, 2, [endDateRangeString UTF8String], -1, SQLITE_TRANSIENT); 
+0

comment est-ce la bonne réponse? – Pavan

+0

Pavan, ai-je tort quelque part? – kovpas

+1

C'est correct car il a corrigé les paramètres de position. Grr, ma réponse similaire est venu en premier :) –

3

Je pense que votre SQL est mauvais. Au lieu de% @ vous devriez utiliser? pour les paramètres de position. Je suggère fortement d'utiliser un emballage pour simplifier la vie. FMDB est un grand à http://github.com/ccgus/fmdb.

0

Ceci est voulu.

sqlite3_step renvoie SQLITE_ROW pour chaque ligne du jeu de résultats et SQLITE_DONE pour indiquer qu'il n'y a plus de lignes. Donc, si un resultset contient N lignes, alors N appels retournerait SQLITE_ROW et (N + 1) st retourne SQLITE_DONE. Un resultset vide n'est en aucun cas spécial, il suit la même logique avec N = 0 (donc le tout premier appel retourne SQLITE_DONE). Cela permet au code client de gérer tous les résultats uniformément.

Espérons que ça aide. Informez-moi si vous avez besoin d'aide.

PK

-1

Si je lis correctement .. Vous n'êtes pas exécuter l'instruction .. vous êtes juste cont .. vous devez faire les deux ..

cette partie juste préparer la requête

if (sqlite3_prepare_v2(database, sql, -1, &stmt, NULL) != SQLITE_OK) 
{ 
      NSLog(@"SQL Warning: failed to prepare statement 
with message '%s'.", sqlite3_errmsg(database)); 
} 

Cette partie exécute en fait la requête

if(sqlite3_exec(database, sql, nil, &stmt, &errmsg) == SQLITE_OK) 
{ 
     NSLog(@"it means that you query executed correctly"); 
     if(sqlite3_step(stmt) == SQLITE_ROW) 
     { 
      NSLog(@"Found!!"); 
     } 
}else 
{ 
     NSLog(@"SQL Warning: '%s'.", sqlite3_errmsg(database)); 
} 

=)

Questions connexes