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

apa*_*apa 13 database sqlite file detection

在下面的代码中,pathToNonDatabase是简单文本文件的路径,而不是真正的sqlite数据库.我希望sqlite3_open能够发现它,但它不是(db不是NULL,而且resultSQLITE_OK).那么,如何检测文件不是有效的sqlite数据库?

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

if((NULL==db) || (result!=SQLITE_OK)) { 
   // invalid database
}
Run Code Online (Sandbox Code Playgroud)

Ste*_*her 16

sqlite懒洋洋地打开数据库.打开后立即做一些事情,要求它成为一个数据库.

最好的可能是pragma schema_version;.

  • 如果尚未创建数据库(例如,空文件),则将报告0.在这种情况下,它是安全的工作(和运行CREATE TABLE等)
  • 如果已创建数据库,则它将返回架构经历的修订数量.这个值可能不是很有趣,但它不是零.
  • 如果文件存在且不是数据库(或空),则会出错.

如果您想要更彻底的检查,您可以使用pragma quick_check;.这是一个更轻量级的完整性检查,它会跳过检查表的内容是否与索引对齐.它仍然可能非常慢.

避免integrity_check.它不仅检查每个页面,而且还根据索引验证表的内容.这对大型数据库来说是积极的.


The*_*der 6

对于需要在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;
    }
Run Code Online (Sandbox Code Playgroud)

如果文件不是有效的数据库,SQLiteException则会引发以下错误-文件已加密或不是数据库(System.Data.SQLite.SQLiteErrorCode.NotADb)。如果您不使用加密数据库,那么此解决方案就足够了。(对于System.Data.SQLite 1.0.81.0版,仅需要'db.Open()',但是当我升级至1.0.91.0版时,必须插入内部using块才能使其正常工作)。