2009-09-14 12 views
5

Attualmente sto facendo quanto segue come parte della mia domanda di iPhonecomportamento SQLite INSERT su 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); 

Quello che mi confonde è che se prendo la sezione,

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

la la INSERT non è salvato nel database e si perde. Presumo che mi manchi qualcosa di ovvio qui?

+0

Sono curioso della vostra ragione (s) per non utilizzare Core Data. – nicerobot

+1

Normalmente utilizzo alcuni wrapper attorno a SQLite o, più spesso di questi, Core Data. Tuttavia volevo sapere come usare direttamente la libreria, quindi ... –

risposta

7

Naturalmente non sarà ottenere inserita. Devi chiamare lo sqlite3_step per eseguire effettivamente la tua dichiarazione.

Controllare the documentation out.

È una cosa SQLITE, non una cosa specifica per iPhone.

Dalla documentazione:

Dopo una dichiarazione preparata è stata preparato utilizzando sqlite3_prepare_v2() o sqlite3_prepare16_v2() o uno dei legacy interfacce sqlite3_prepare() o sqlite3_prepare16(), questo la funzione deve essere chiamata una o più volte a valutare la dichiarazione.

+0

La documentazione di SQLite non è straordinariamente ben strutturata. Grazie per il puntatore. –

+0

... ma sì, mi mancava qualcosa di ovvio. –

2

vorrei totalmente consiglia di utilizzare un wrapper invece di trattare con dichiarazioni compilazione te stesso ... Una lista decente di opzioni è disponibile qui: http://cocoaheads.byu.edu/resources/sqlite

2

Stai inserendo solo una riga qui, quindi c'è molto codice di codice. Pensate a che cosa accadrebbe se si voleva inserire più righe:

  • saresti ancora bisogno di una singola dichiarazione preparare
  • Farebbe ancora bisogno di una singola istruzione finalizzazione
  • Avreste bisogno di una dichiarazione passo per ogni riga che si desidera aggiungere. Puoi pensare al "passaggio" come "esegui" (o "ottieni la riga successiva" se stai guardando un'istruzione SELECT)

A proposito, probabilmente non vuoi "fare un passo" "se la dichiarazione preparata è fallita.

0

Utilizzare il codice

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

invece di "inserire nel"

Problemi correlati