2013-02-16 11 views
5

Ho un'applicazione che accede di frequente un database SQLite. E le grandi opere la maggior parte del tempo, ma di tanto in tanto in una delle mie funzioni di database non riesce e restituisce:file casuale SQLite è crittografato o non è un database

file è crittografato o non è un database

non ho alcuna crittografia abilitato ma non posso per capire come sta succedendo. Non è riproducibile in modo coerente e dai registri degli arresti anomali, si verifica sul thread principale.

Grazie in anticipo.

@synchronized(self) { 
    sqlite3 *database = mydb; 
    int result = 0; 

    static sqlite3_stmt *stmt = nil; 
    if (stmt == nil) { 
     const char *sql = "select sum(not isAvailable) from table1 e inner join table2 f on e.key=f.pk where f.pk=? AND e.isDeleting=0;"; 
     if (sqlite3_prepare_v2(database, sql, -1, &stmt, NULL) != SQLITE_OK) { 
      NSAssert1(0, @"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database)); 
     } 
    } 

    sqlite3_bind_int(stmt, 1, obj.primaryKey); 

    if (sqlite3_step(stmt) == SQLITE_ROW) { 
     int val = sqlite3_column_int(stmt, 0); 
     result = val; 
    } else { 
     [NSException raise:@"SQL Fail" format:@"SQL Failed: %s", sqlite3_errmsg(database)]; 
    } 
    // Reset the statement for future reuse. 
    sqlite3_reset(stmt); 

    return result; 
} 
+0

Versione non corrispondente forse? – CodaFi

+0

ho chiesto a google e la risposta più popolare è la mancata corrispondenza della versione, ma non capisco come questo possa accadere solo qualche volta per questa query ... post aggiornato con codice di esempio – VTS12

+0

@CodaFi - Sono abbastanza sicuro che la versione del file SQLite non è cambiato in modo incompatibile in un certo numero di anni. "La mancata corrispondenza della versione" è la solita spiegazione offerta, ma non spiega nulla. –

risposta

0

L'errore si verifica quando il file di DB diventa in qualche modo confuso. Esattamente perché questo potrebbe accadere, però, è un po 'un puzzle.

Se si sta scrivendo altri file nella vostra applicazione, si può avere accidentalmente sovrascritto il file di DB. E se si dovesse aprire lo stesso file di DB due volte o fare due operazioni "simultanei" a DB si potrebbe essere in grado di creare questo scenario (ma credo che la maggior parte delle versioni di SQLite sono compilate con il codice per rilevare questo e l'errore fuori se c'è un conflitto). (Domanda: Hai mai ricevuto l'errore "database è bloccato" invece?)

+0

sto scrivendo anche su un file di log ... ma la cosa strana è dopo che ho ricevuto questo errore, l'app funziona al prossimo avvio come se non fosse successo niente ... non ho visto il database bloccato o – VTS12

+0

@HotLicks In che modo "in qualche modo confondibile" è meno vago (in linea di principio) di una versione non corrispondente? Un database incomprensibile può essere causato da qualcosa di semplice come non eseguire una transazione, e qualcosa di così complicato come rendere difficile la migrazione a una nuova versione. – CodaFi

+0

@CodaFi - Una mancata corrispondenza della versione (se possibile) non si verificherebbe a meno che non sia installata una nuova versione di DB o di SQLite, quindi non potrebbe mai "accadere" con un'app che funziona in precedenza. E devo credere che ci sia un messaggio di errore separato per la mancata corrispondenza della versione, rispetto al messaggio crittografato. –

1

Per creare un nuovo database SQLite crittografato o per aprire un database SQLite crittografato esistente devi chiamare la funzione sqlite3_key o eseguire una "chiave pragma" = "comando immediatamente dopo l'apertura del database prima di eseguire qualsiasi altra operazione di database. Ho il sospetto che si è tentato di aprire un database esistente, ma non codificata database SQLite e aspettavo per crittografare esso utilizzando uno dei metodi di cui sopra. Questo non funziona ma restituisce il messaggio di errore che hai riscontrato. Per crittografare un database SQLite non crittografato esistente è necessario utilizzare la funzione sqlite3_rekey o "= pragma rekey" comando. Per modificare la chiave di crittografia di un database SQLite crittografato esistente si deve aprire il database, quindi di utilizzare sqlite3_key (o "chiave pragma =") e poi di applicare sqlite3_rekey (o "pragma Rekey =").

0

Per quanto sia sconsigliabile il consiglio di "mancata corrispondenza della versione", ho riscontrato gli stessi sintomi e ho riscontrato che il problema veniva risolto aggiornando il database dalla versione 2 alla 3. Forse uno dei motivi per cui questo problema si verifica è che il l'estensione del file per il database non riflette necessariamente correttamente il numero di versione reale.

Potrei sbagliarmi, ma quando ho creato il mio primo database SQLite utilizzando la versione 0.8.3.2 di SQLite Administrator e accettato il "Salva come tipo" di SQLite3 DB, il file creato era apparentemente un DB versione 2 nonostante avesse un .s3db name. Sotto il menu Database, la voce "Migrate to SQLite3" è stata abilitata, ma ho capito che si trattava di un errore nella GUI. Tuttavia, dopo aver utilizzato questa funzione, il mio problema è scomparso.

Utilizzo successivo del database | Nuova opzione in SQLite Administrator crea un DB della versione scelta e l'estensione del file corrisponde alla convenzione per quella versione. Il comportamento errato di SQL Administrator si è verificato solo la prima volta che ho utilizzato l'opzione Database | Nuova.

0

Ho avuto lo stesso problema oggi.

Si è scoperto che stavo creando una colonna denominata Ora nel mio database. L'ho cambiato in TimeStamp e ha funzionato. Ho pensato che in qualche modo il mio file fosse stato corrotto, quindi stavo guardando il codice sql per generare la tabella (per rifarlo su un nuovo file) quando ho notato "Time" evidenziato in blu che indicava che era una parola riservata.

Problemi correlati