2009-09-14 12 views
5

Je fais actuellement les éléments suivants dans le cadre de mon application iPhonecomportement SQLite sur INSERT sur iPhone

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *documentsPath = [paths objectAtIndex:0]; 
NSString *filePath = [documentsPath stringByAppendingPathComponent:@"cities.sqlite"]; 

sqlite3 *database; 

if(sqlite3_open([filePath UTF8String], &database) == SQLITE_OK) { 
    const char *sqlStatement = "insert into table (name, description, image) VALUES (?, ?, ?)"; 
    sqlite3_stmt *compiledStatement; 
    if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) { 
     sqlite3_bind_text(compiledStatement, 1, [name UTF8String], -1, SQLITE_TRANSIENT); 
     sqlite3_bind_text(compiledStatement, 2, [description UTF8String], -1, SQLITE_TRANSIENT); 
     NSData *dataForImage = UIImagePNGRepresentation(image); 
     sqlite3_bind_blob(compiledStatement, 3, [dataForImage bytes], [dataForImage length], SQLITE_TRANSIENT); 

    } 
    if(sqlite3_step(compiledStatement) != SQLITE_DONE) { 
     NSLog(@"Error: %s", sqlite3_errmsg(database)); 
    } else { 
     NSLog(@"Insert into row id = %d", sqlite3_last_insert_rowid(database)); 
    } 
    sqlite3_finalize(compiledStatement); 
} 
sqlite3_close(database); 

Qu'est-ce qui me confondant est que si je prends la section,

if(sqlite3_step(compiledStatement) != SQLITE_DONE) { 
     NSLog(@"Error: %s", sqlite3_errmsg(database)); 
    } else { 
     NSLog(@"Insert into row id = %d", sqlite3_last_insert_rowid(database)); 
    } 

le la INSERT n'est pas enregistré dans la base de données et est perdu. Je présume qu'il me manque quelque chose d'évident ici?

+0

Je suis curieux de votre raison (s) pour ne pas utiliser de base de données. – nicerobot

+1

J'utilise normalement des wrappers autour de SQLite ou, plus souvent qu'aujourd'hui, Core Data. Cependant, je voulais savoir comment utiliser la bibliothèque directement, alors ... –

Répondre

7

Bien sûr, il ne sera pas inséré. Vous devez appeler sqlite3_step pour exécuter votre déclaration.

Vérifiez the documentation sur.

C'est une chose SQLITE, pas une chose spécifique à l'iPhone.

De la documentation:

Après une déclaration préparée a été préparé en utilisant soit sqlite3_prepare_v2() ou sqlite3_prepare16_v2() ou l'un des sqlite3_prepare interfaces héritées () ou sqlite3_prepare16(), ce la fonction doit être appelée une ou plusieurs fois pour évaluer l'instruction.

+0

La documentation SQLite n'est pas incroyablement bien présentée. Merci pour le pointeur. –

+0

... mais oui, il me manquait quelque chose d'évident. –

2

Je voudrais totalement vous recommandons d'utiliser un emballage au lieu de traiter les déclarations compilant vous ... Une bonne liste d'options est disponible ici: http://cocoaheads.byu.edu/resources/sqlite

2

Vous n'insérez qu'une ligne ici, donc il y a beaucoup de code standard. Pensez à ce qui se passerait si vous vouliez insérer plusieurs lignes:

  • Vous auriez encore besoin d'une seule instruction préparer
  • Vous auriez encore besoin d'un seul Finaliser déclaration
  • Vous auriez besoin d'une instruction étape pour chaque ligne que vous voulez ajouter. Vous pouvez penser que "step" est "execute" (ou "get next row" si vous regardez une instruction SELECT)

D'ailleurs, vous ne voulez probablement pas "marcher" "si l'instruction préparée a échoué.

0

Utilisez le code

const char *sqlStatement = "REPLACE INTO table (name, description, image) VALUES (?, ?, ?)"; 

au lieu de "insérer dans"