如果数据库丢失,使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; } } 

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

  • 数据库文件已被移动/删除。

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

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

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

至少在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连接字符串示例,查找“禁用创建数据库行为”。

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

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

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

pragma integrity_check;

要么

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

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

否则,它将报告遇到的错误。

对于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#代码

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

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