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

Posted

技术标签:

【中文标题】如何判断 sqlite 数据库文件是不是有效【英文标题】:How to tell if sqlite database file is valid or not如何判断 sqlite 数据库文件是否有效 【发布时间】:2011-04-22 18:11:46 【问题描述】:

在下面的代码中,pathToNonDatabase 是一个简单文本文件的路径,而不是一个真正的 sqlite 数据库。我希望sqlite3_open 能够检测到这一点,但它没有(db 不是NULLresultSQLITE_OK)。那么,如何检测文件不是有效的sqlite数据库呢?

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

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

【问题讨论】:

【参考方案1】:

sqlite 懒惰地打开数据库。只需在打开后立即执行一些要求它是数据库的操作。

最好的可能是pragma schema_version;

如果尚未创建数据库(例如,一个空文件),这将报告 0。在这种情况下,使用(并运行 CREATE TABLE 等)是安全的 如果数据库已经创建,它将返回架构经历了多少次修订。这个值可能不有趣,但它不为零。 如果文件存在且不是数据库(或为空),则会出现错误。

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

避免integrity_check。它不仅会检查每一页,还会根据索引验证表的内容。这在大型数据库上是非常缓慢的。

【讨论】:

"pragma schema_version;"有时会抛出“数据库已锁定”错误。我会给出“pragma quick_check;”试一试 如果您的数据库被锁定,它就被锁定。一切都会失败。未锁定时重试。 :) 你是对的。当数据库被锁定时,一切都会失败。甚至选择。就我而言,我想确定该文件是否是 Sqlite3 数据库。如果我收到“数据库已锁定”错误,我认为可以安全地假设该文件是 Sqlite3 数据库。 这不适用于加密数据库(例如使用 SQLCipher)。 不,它不会,除非你用同一个钥匙解锁它。这就是 SQLite 的设计方式,而 SQLCipher 就是对它的一种破解。【参考方案2】:

对于需要在 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)。如果您不使用加密数据库,那么这个解决方案就足够了。 (System.Data.SQLite 的 1.0.81.0 版只需要“db.Open()”,但是当我升级到 1.0.91.0 版时,我必须插入内部 using 块才能使其工作)。

【讨论】:

【参考方案3】:

我认为编译指示完整性检查可以做到这一点。

【讨论】:

被警告;如果您的数据库很大,这可能会非常慢。【参考方案4】:

如果您只想检查文件是否是有效的 sqlite 数据库,则可以使用此函数进行检查:

    private bool CheckIfValidSQLiteDatabase(string databaseFilePath)
    
        byte[] bytes = new byte[16];
        using (FileStream fileStream = new FileStream(databaseFilePath, FileMode.Open, FileAccess.Read))
        
            fileStream.Read(bytes, 0, 16);
        
        string gg = System.Text.ASCIIEncoding.ASCII.GetString(bytes);
        return gg.Contains("SQLite format");
    

如文档中所述: sqlite database header

【讨论】:

以上是关于如何判断 sqlite 数据库文件是不是有效的主要内容,如果未能解决你的问题,请参考以下文章

如何批量判断excel里面链接的有效性(是不是可以打开)?

JAVA判断一个URL是不是有效

sqlite怎么判断表里面是不是有数据。not exists

怎么判断sqlite3中某个表是不是已经存在

如何判断 ALTER PROCEDURE 是不是有效?

如何判断 jetpack-compose 分页是不是有效?