如果数据库丢失,使SQLite连接失败? (删除/移动)

时间:2009-04-30 14:30:59

标签: c# sqlite

我在class DBConnection内有以下方法。当我想打开连接时,我调用这样的方法:SQLiteConnection conn = DBConnection.OpenDB();,以便我可以执行查询。当我想关闭连接时,我可以调用类似的方法。

方法:

public static SQLiteConnection OpenDB()
{
    try
    {
        //Gets connectionstring from app.config
        string myConnectString =
            ConfigurationManager.ConnectionStrings[
                "LegMedSQLLite.Properties.Settings.LegMedSQLLiteDBConnectionString"].ConnectionString;

        var conn = new SQLiteConnection(myConnectString);

        conn.Open();
        return conn;
    }
    catch (SQLiteException e)
    {
        MessageBox.Show(e.ToString(), "TEST");
        return null;
    }
}

这一切都很好,花花公子。问题是尝试捕获。让我们想象以下场景:

  • 数据库文件已经存在 移除/删除。

永远不会抛出异常。实际上,我偶然发现的第一个问题是当我执行我的第一个查询时 - 它认为没有这样的表,它会抛出自己的异常。 我被这种奇怪的现象震惊了,但我很快发现SQLite创造了一个新的 数据库。空是意味着没有表,什么都没有,只是一个SQLT数据库文件,其名称与应该存在的旧数据库相同。

这是一个问题,我希望应用程序在我尝试调用SQLiteConnection conn = DBConnection.OpenDB();时知道是否有错误(数据库未找到,已损坏,被其他进程使用等)。

当然,我可以尝试在我的方法中调用File.Exists,但这似乎不是一个合适的解决方案。有什么帮助吗?

6 个答案:

答案 0 :(得分:19)

至少在System.Data.SQLite中,您可以在连接字符串中添加“ FailIfMissing=True ”。如果数据库文件不存在,SQLiteConnection.Open()将抛出SQLiteException

string ConnectString = "Data Source=file.sdb; FailIfMissing=True";
DbConnection db = new SQLiteConnection(ConnectString);
db.Open(); // Fails if file.sdb does not exist

有关其他示例,请参阅SQLite Connection String Samples,查找“禁用创建数据库行为”。

答案 1 :(得分:2)

我没有使用过SQLite,但这对于自动创建一个全新的数据库来说是非常奇怪的行为。

您可以在打开连接后立即调整try块以执行Select top 1 * From Table,如果有效,则丢弃结果并继续返回conn对象。如果失败,则应触发异常处理程序。

答案 2 :(得分:1)

如果要在启动时检测数据库损坏问题,可以执行命令

pragma integrity_check;

pragma quick_check; (这更快,但不太彻底)

这将返回值为“ok”的单行。

否则会报告遇到的错误。

答案 3 :(得分:0)

对于sqlite使用此:假设您在textbox中有连接字符串txtConnSqlite

     Using conn As New System.Data.SQLite.SQLiteConnection(txtConnSqlite.Text)
            Dim FirstIndex As Int32 = txtConnSqlite.Text.IndexOf("Data Source=")
            If FirstIndex = -1 Then MsgBox("ConnectionString is incorrect", MsgBoxStyle.Exclamation, "Sqlite") : Exit Sub
            Dim SecondIndex As Int32 = txtConnSqlite.Text.IndexOf("Version=")
            If SecondIndex = -1 Then MsgBox("ConnectionString is incorrect", MsgBoxStyle.Exclamation, "Sqlite") : Exit Sub
            Dim FilePath As String = txtConnSqlite.Text.Substring(FirstIndex + 12, SecondIndex - FirstIndex - 13)
            If Not IO.File.Exists(FilePath) Then MsgBox("Database file not found", MsgBoxStyle.Exclamation, "Sqlite") : Exit Sub
            Try
                conn.Open()
                Dim cmd As New System.Data.SQLite.SQLiteCommand("SELECT * FROM sqlite_master WHERE type='table';", conn)
                Dim reader As System.Data.SQLite.SQLiteDataReader
                cmd.ExecuteReader()
                MsgBox("Success", MsgBoxStyle.Information, "Sqlite")
            Catch ex As Exception
                MsgBox("Connection fail", MsgBoxStyle.Exclamation, "Sqlite")
            End Try
         End Using

我认为您可以轻松将其转换为c#code

答案 4 :(得分:-1)

不要抓住那个级别。相反,SQLiteConnection应该实现IDisposable,这意味着您应该只返回打开的连接并允许调用代码来处理任何异常,并依赖Dispose方法来关闭连接。

答案 5 :(得分:-2)

如果无法更改默认的SQLite行为,则可能需要执行File.Exists。这比连接和创建新文件更好,检查它是否是您想要的数据库,然后删除catch块中的新文件。