如何判断sqlite数据库文件是否有效

问题描述:

在下面的代码中,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 
} 

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

我认为一个编译指示integrity_check可以做到这一点。

+0

被警告;如果数据库很大,这可能会很慢。 – 2014-01-27 18:25:51

对于任何需要做这在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时,我不得不插入内部使用块来使其工作)。