2010-08-06 4 views
1

J'essaie donc de travailler avec SQLite dans l'une des applications iPhone et j'utilise la bibliothèque sqlite3. Je suis capable d'accéder à la base de données et même de faire une requête; en fait, la requête accède aux données exactes mais pour une raison quelconque, la chaîne que je récupère est un entier long et non la chaîne que je cherchais. Voici la base de données et le code:iPhone Base de données SQLite Lecture et écriture

 
Filename: Package.sql 
Table Lessons 
LessonID VARCHAR(64) Primary Key | LessonName VARCHAR(100) | EntryDate (DATETIME) | Chrono VARCHAR (20) 
bfow02nso9xjdo40wksbfkekakoe29ak | Learning The History | 2010-08-05 16:24:35 | 0001 

et le code iPhone

 
... 
-(NSString *)getRow:(NSString *)tablename where:(NSString *)column equals:(NSString *)value { 

  const char *query = [[[[[[[@"SELECT * FROM `" stringByAppendingString:tablename] stringByAppendingString:@"` WHERE `"] stringByAppendingString:column] stringByAppendingString:@"` = '"] stringByAppendingString:value] stringByAppendingString:@"';"] cStringUsingEncoding:NSUTF8StringEncoding]; 

  NSString *result; 

  if(sqlite3_open([dbpath UTF8String], &database) == SQLITE_OK) { 

    sqlite3_stmt *compiledQuery; 

    if(sqlite3_prepare_v2(database, query, -1, &compiledQuery, NULL) == SQLITE_OK) { 

      while(sqlite3_step(compiledQuery) == SQLITE_ROW) { 

        NSString *str_temp = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledQuery, 2)]; 

        result = str_temp; 
         
      } 

      sqlite3_finalize(compiledQuery); 

    } 

    sqlite3_close(database); 

  } 
  
  return result; 

} 
... 

Lorsque le code est exécuté:

 
    CDatabase *db = [[CDatabase alloc]initWithDatabase:@"Package.sql"]; 
    NSString *result = [db getRow:@"Lessons" where:@"Chrono" equals:@"0001"]; 

la valeur renvoyée résultat NSString de * a une valeur de "1364111" . Pourquoi fait-il ça ??? Il devrait être "Apprendre l'historique"

+0

Vous devriez essayer FMDatabase de Gus Mueller. Je l'utilise dans mes projets, et cela fait très bien le travail. (N'oubliez pas de conserver l'objet FMDatabase si vous voulez l'utiliser dans toute l'application.) –

Répondre

0

Haha oups je réalisais que je ne faisais que l'affichage de la chaîne comme un format de données en utilisant le format de chaîne %d. quand je l'ai changé à %@ j'ai obtenu le format de chaîne

2

Êtes-vous sûr que l'un de vos appels SQLite a réussi? Vous devez initialiser result à nil afin que votre fonction renvoie nil si des erreurs sont détectées.

Trois (probablement liés) des problèmes avec votre code:

  1. L'index sqlite3_column_text doit être basé sur zéro; vous passez 2, ce qui devrait se référer à la troisième colonne. Vous voulez probablement passer 1. De the docs:

    ... le deuxième argument est l'index de la colonne pour laquelle les informations doivent être retournées. La colonne la plus à gauche de l'ensemble de résultats a l'index 0.

  2. Vous ne devriez pas utiliser SELECT *. Spécifiez les colonnes que vous voulez!

  3. Vous devriez spécialiser votre requête en liant des valeurs, pas en concaténant des chaînes! Votre code est très répandu avec la possibilité d'injections SQL (sans parler des requêtes incorrectes).

Par exemple (sans vérification d'erreur):

const char *query = "SELECT * FROM ? WHERE ?=?"; 
sqlite3_stmt *compiledQuery; 
sqlite3_prepare_v2(database, query, -1, &compiledQuery, NULL); 
sqlite3_bind_text(compiledQuery, 1, "Lessons", -1, SQLITE_TRANSIENT); 
sqlite3_bind_text(compiledQuery, 2, "Chrono", -1, SQLITE_TRANSIENT); 
sqlite3_bind_text(compiledQuery, 3, "0001", -1, SQLITE_TRANSIENT); 

Notez que l'indice est ici 1 à base (je ne sais pas pourquoi ils le font). À partir du docs:

Le deuxième argument est l'index du paramètre SQL à définir. Le paramètre SQL plus à gauche a un indice de 1.

+0

Merci pour la réponse rapide! J'ai trouvé une autre façon d'écrire le code, mais je vais essayer le vôtre. Cela avait à voir avec le type d'encodage de chaîne que j'utilisais. –

Questions connexes