2010-10-08 10 views
11

W poniższym kodzie pathToNonDatabase jest ścieżką do prostego pliku tekstowego, a nie prawdziwą bazą danych SQLite. Miałem nadzieję, że to wykryje sqlite3_open, ale nie ma (db nie jest NULL i result jest SQLITE_OK). Jak wykryć, że plik nie jest prawidłową bazą danych sqlite?Jak stwierdzić, czy plik bazy danych SQL jest prawidłowy czy nie

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

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

Odpowiedz

12

sqlite otwiera lazily bazy danych. Zrób coś natychmiast po otwarciu, co wymaga, aby była bazą danych. Jest to prawdopodobnie pragma schema_version;.

  • Spowoduje to zgłoszenie 0, jeśli baza danych nie została utworzona (na przykład pusty plik). W tym przypadku jest to bezpieczna praca z (i uruchomić CREATE TABLE, itp.)
  • Jeśli baza danych została utworzona, zwróci liczbę wersji, które przeszły przez schemat. Ta wartość może nie być interesująca, ale nie jest równa zero.
  • Jeśli plik istnieje i nie jest bazą danych (lub pusty), pojawi się błąd.

Jeśli chcesz nieco dokładniej sprawdzić, możesz użyć pragma quick_check;. Jest to lżejsza kontrola integralności, która pomija sprawdzanie, czy zawartość tabel jest zgodna z indeksami. Nadal może być bardzo powolny.

Należy unikać integrity_check. Sprawdza nie tylko każdą stronę, ale także weryfikuje zawartość tabel względem indeksów. Jest to pozytywnie lodowaty na dużej bazie danych.

+1

"pragma schema_version;" czasem wyrzuca błąd "baza danych jest zablokowana". Dam ci "pragma quick_check;" a spróbuj –

+1

Jeśli twoja baza danych jest zablokowana, jest zablokowana. Wszystko zawiedzie. Spróbuj ponownie, gdy nie jest zablokowany. :) –

+0

Masz rację. Wszystko zawiedzie, gdy baza danych jest zablokowana. Nawet wybiera. W moim przypadku chciałem ustalić, czy plik jest bazą danych Sqlite3. Jeśli otrzymam komunikat "baza danych jest zablokowana", myślę, że można bezpiecznie założyć, że plik jest bazą danych Sqlite3. –

2

Myślę, że może to zrobić pragma integrity_check.

+0

Ostrzegam; może to być bardzo powolne, jeśli twoja baza danych jest duża. –

4

Dla każdego, która chciałaby to zrobić w C# z System.Data.SQLite można rozpocząć transakcję, a następnie natychmiast zwinąć go w następujący sposób: -

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; 
    } 

Jeśli plik nie jest prawidłowym Database po zgłoszeniu SQLiteException - plik jest zaszyfrowany lub nie jest bazą danych (System.Data.SQLite.SQLiteErrorCode.NotADb). Jeśli nie korzystasz z zaszyfrowanych baz danych, to rozwiązanie powinno wystarczyć. (Tylko wersja db.Open() była wymagana dla wersji 1.0.81.0 z System.Data.SQLite, ale po aktualizacji do wersji 1.0.91.0 musiałem wstawić wewnętrzny blok, aby go uruchomić).

Powiązane problemy