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

问题描述:

我在class DBConnection里面有以下方法。我打电话的方法是这样的:SQLiteConnection conn = DBConnection.OpenDB();当我想打开一个连接,以便我可以执行我的查询。当我想关闭连接时,我可以调用类似的方法。如果数据库丢失,使SQLite连接失败? (删除/移动)

的方法:

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创建了一个新的 空的数据库。空的意思是没有表,什么都没有,只是一个SQLite数据库文件,与原本应该存在的旧数据库名称相同。

这是一个问题,只要我尝试拨打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 Connection String Samples,寻找“禁用创建数据库的行为”。

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

你可以只调整try块做Select top 1 * From Table你打开连接后,如果它的工作原理,扔掉结果,并继续回到你的conn对象。如果失败,异常处理程序应该触发。

+1

是啊,我还以为是的! 但是,它似乎并不完全是System.Data.SQLite这样做的。我知道SQLite的Web服务器使用相同。 另外,我也想过SQL查询的想法,但它看起来像这样的浪费。如果没有“适当”的方式来做到这一点,我一定会将您的答案标记为已接受的答案。 – CasperT 2009-04-30 14:40:39

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

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

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

编译INTEGRITY_CHECK;

pragma quick_check; (这是更快,但不太全面)

这将返回一个值为“OK”的单行。

否则它会报告它遇到的错误。

SQLite的使用这样的:假设你有连接字符串中的文本框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 

我认为你可以easilly其转换为C#代码