2010-10-08 76 views
11

在下面的代碼中,pathToNonDatabase是簡單文本文件的路徑,而不是真正的sqlite數據庫。我希望sqlite3_open檢測到,但它不(db不是NULLresultSQLITE_OK)。那麼,如何檢測文件不是有效的sqlite數據庫?如何判斷sqlite數據庫文件是否有效

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

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

回答

12

sqlite懶洋洋地打開數據庫。只需在打開之後立即執行某項操作,即需要將其作爲數據庫。

最好的可能是pragma schema_version;

  • 如果還沒有創建數據庫(例如,空文件),這將報告0。在這種情況下,安全工作(並運行CREATE TABLE等)
  • 如果數據庫已創建,它將返回架構經過的修訂數量。這個值可能不是有趣的,但它不是零。
  • 如果文件存在並且不是數據庫(或空),則會出現錯誤。

如果您想要進行更徹底的檢查,您可以使用pragma quick_check;。這是一個輕量級的完整性檢查,它會跳過檢查表中的內容與索引是否一致。它仍然可能非常緩慢。

避免integrity_check。它不僅檢查每個頁面,還會根據索引驗證表格的內容。這對大型數據庫來說是積極的。

+1

「pragma schema_version;」有時會拋出「數據庫被鎖定」錯誤。我會給「快速檢查」;試試 – 2014-03-13 02:13:30

+1

如果你的數據庫被鎖定,它就被鎖定了。一切都會失敗。未鎖定時再試一次。 :) – 2014-03-13 02:25:56

+0

你說得對。數據庫被鎖定時一切都會失敗。即使選擇。在我的情況下,我想確定該文件是否是Sqlite3數據庫。如果我得到「數據庫已鎖定」錯誤,我認爲假定文件是Sqlite3數據庫是安全的。 – 2014-03-13 02:38:23

2

我認爲一個編譯指示integrity_check可以做到這一點。

+0

被警告;如果數據庫很大,這可能會很慢。 – 2014-01-27 18:25:51

4

對於任何需要做這在C#與System.Data.SQLite你就可以開始交易,然後立即回滾如下: -

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

如果該文件是不是有效的數據庫在拋出SQLiteException後 - 文件被加密或不是數據庫(System.Data.SQLite.SQLiteErrorCode.NotADb)。如果你不使用加密數據庫,那麼這個解決方案應該足夠了。 (只有'db.Open()'對於System.Data.SQLite 1.0.81.0版本是必需的,但是當我升級到版本1.0.91.0時,我不得不插入內部使用塊來使其工作)。

相關問題