2011-12-04 14 views
8

Sai perché ricevo "Routine di libreria chiamata di sequenza" quando chiamo sqlite3_prepare_v2(CREATE TABLE) in un database vuoto?"Routine di libreria chiamata fuori sequenza" sqlite3_prepare_v2 (CREATE TABLE)

Creo un database vuoto e quindi lo apro. Successivamente, salverò tutte le informazioni che devono essere scritte nel database nella RAM (ho bisogno di salvare quelle informazioni nella RAM e di scaricarle nella memoria permanente alla fine dell'esecuzione), ma ricevo questo messaggio di errore quando chiamo sqlite3_prepare_v2(CREATE TABLE). Restituisce "Routine di libreria chiamata fuori sequenza" come messaggio di errore.

io apro il mio database correttamente e (ho pensato che può essere un problema così ho fatto il mio close() DB e poi open() a destra prima di chiamare sqlite3_prepare_v2(CREATE TABLE)). Ho pensato che potrebbe essere a causa della concomitanza di thread, ma l'utilizzo della sezione critica non ha aiutato troppo.

risposta

11

Questo è ciò che l'documentation dice di cause per il vostro errore:

  1. Calling any API routine with an sqlite3* pointer that was not obtained from sqlite3_open() or sqlite3_open16() or which has already been closed by sqlite3_close().
  2. Trying to use the same database connection at the same instant in time from two or more threads.
  3. Calling sqlite3_step() with a sqlite3_stmt* statement pointer that was not obtained from sqlite3_prepare() or sqlite3_prepare16() or that has already been destroyed by sqlite3_finalize().
  4. Trying to bind values to a statement (using sqlite3_bind_...()) while that statement is running.

Lei ha parlato di provare una sezione critica, quindi credo che possiamo escludere 2 #. Il tuo errore è il risultato di una chiamata a sqlite3_prepare_v2 (...), non a sqlite3_step() o a sqlite3_bind(), quindi immagino che rimanga solo # 1? Puoi ricontrollare che il tuo puntatore db sia buono? Rintracciatelo a sqlite3_open() che lo ha restituito e assicuratevi che nulla lo abbia chiuso prima che venga chiamato il vostro preparativo?

questo funziona per me:

#include <stdio.h> 
#include <sqlite3.h> 

int main(int argc, char **argv){ 

    sqlite3 *db; 
    int rc; 

    char *db_name= ":memory:"; 

    rc = sqlite3_open(db_name, &db); 

    if (rc != SQLITE_OK) { 
     fprintf(stderr, "failed to open in memory database: %s\n", 
       sqlite3_errmsg(db)); 
     sqlite3_close(db); 
     return(1); 
    } 

    const char *create_sql = "CREATE TABLE foo(bar TEXT)"; 
    sqlite3_stmt *statement; 

    rc = sqlite3_prepare_v2(db, create_sql, -1, &statement, NULL); 

    if (rc != SQLITE_OK) { 
     fprintf(stderr, "failed to prepare statement: %s\n", 
       sqlite3_errmsg(db)); 
     sqlite3_close(db); 
     return(1); 
    } 

    rc = sqlite3_step(statement); 

    if (rc == SQLITE_ERROR) { 
     fprintf(stderr, 
       "failed to execute statement: %s\n", 
       sqlite3_errmsg(db)); 
    } 

    sqlite3_close(db); 

} 
+0

Mark grazie mille questo esempio ha aiutato. Ho ancora una domanda (scusa se è troppo sciocco, ma sono nuovo di sql). Quando scrivi per nome database char * db_name = ": memoria:"; rc = sqlite3_open (db_name, verrà creato &db); questo significa che base di dati in RAM? Se questo è il caso si può spiegare come alla fine di questo codice posso irrigare file di database di memorizzazione permanente? – user1079655

+1

+1 per rimanendo con esso fino alla fine :) –

1

Tutte le soluzioni sopra sono esatte.

However, May be possible that you have written wrong column name or by mistake wrong column name entered in your query that you want to execute.

Perché nel mio caso ho ottenuto l'errore molte volte dopo che ho controllare il codice riga per riga e ho trovato il mio errore

1

Nel mio caso si trattava di una stringa contenente alcuni caratteri speciali come se fosse (') singolo punto i lo ha sostituito con ("") uno spazio e inizia a funzionare. [yourString stringByReplacingOccurrencesOfString: @ "'" withString: @ ""]

Problemi correlati