2010-10-08 22 views
11

En el código siguiente, pathToNonDatabase es la ruta a un archivo de texto simple, no a una base de datos sqlite real. Esperaba sqlite3_open para detectar eso, pero no (db no es NULL, y result es SQLITE_OK). Entonces, ¿cómo detectar que un archivo no es una base de datos SQLite válida?Cómo saber si el archivo de base de datos sqlite es válido o no

sqlite3 *db = NULL; 
int result = sqlite3_open(pathToNonDatabase, &db); 

if((NULL==db) || (result!=SQLITE_OK)) { 
    // invalid database 
} 

Respuesta

12

sqlite abre las bases de datos con pereza. Simplemente haga algo inmediatamente después de la apertura que requiera que sea una base de datos.

Lo mejor es probablemente pragma schema_version;.

  • Esto informará 0 si la base de datos no se ha creado (por ejemplo, un archivo vacío). En este caso, es seguro trabajar con (y ejecutar CREATE TABLE, etc.)
  • Si se ha creado la base de datos, devolverá cuántas revisiones ha realizado el esquema. Este valor puede no ser interesante, pero que no es cero es.
  • Si el archivo existe y no es una base de datos (o está vacío), obtendrá un error.

Si desea una verificación algo más completa, puede usar pragma quick_check;. Esta es una verificación de integridad más liviana, que omite verificar que el contenido de las tablas se alinee con los índices. Todavía puede ser muy lento.

Evitar integrity_check. No solo verifica todas las páginas, sino que luego verifica los contenidos de las tablas con los índices. Esto es positivamente glacial en una gran base de datos.

+1

"pragma schema_version;" lanza el error "la base de datos está bloqueada" a veces. Le daré el "pragma quick_check"; una prueba –

+1

Si su base de datos está bloqueada, está bloqueada. Todo fallará Inténtalo de nuevo cuando no esté bloqueado. :) –

+0

Tienes razón. Todo falla cuando la base de datos está bloqueada. Incluso selecciona. En mi caso, quería determinar si el archivo era una base de datos Sqlite3. Si obtengo el error "la base de datos está bloqueada", creo que es seguro suponer que el archivo es una base de datos Sqlite3. –

2

Creo que una pragma integrity_check podría hacerlo.

+0

Tenga cuidado; esto puede ser muy lento si su base de datos es grande. –

4

para cualquiera que necesite hacer esto en C# con System.Data.SQLite puede iniciar una transacción, e inmediatamente rodar de nuevo de la siguiente manera: -

private bool DatabaseIsValid(string filename) 
    { 
     using (SQLiteConnection db = new SQLiteConnection(@"Data Source=" + filename + ";FailIfMissing=True;")) 
     { 
      try 
      { 
       db.Open(); 
       using (var transaction = db.BeginTransaction()) 
       { 
        transaction.Rollback(); 
       } 
      } 
      catch (Exception ex) 
      { 
       log.Debug(ex.Message, ex); 
       return false; 
      } 
     } 
     return true; 
    } 

Si el archivo no es una base de datos válida la Se arroja el siguiente SQLiteException: el archivo está encriptado o no es una base de datos (System.Data.SQLite.SQLiteErrorCode.NotADb). Si no está utilizando bases de datos cifradas, esta solución debería ser suficiente. (Solo se necesitó el 'db.Open()' para la versión 1.0.81.0 de System.Data.SQLite, pero cuando actualicé a la versión 1.0.91.0 tuve que insertar el bloque de uso interno para que funcione).

Cuestiones relacionadas