2013-10-24 64 views
1

我目前正在從事數據庫挖掘程序從sqlite數據庫中提取數據並填充表單。這需要從幾張不同的表中同時提取幾種類型的數據,而且似乎需要大量資源。有沒有更好的方法來解決這個問題?我應該使用後臺工作來運行sql查詢嗎?我正在運行多個SQLiteCommand.ExecuteReader實例,是否可以避免這種情況?vb.net - sqlite - 在一個連接中選擇多個值

代碼:

Public Shared Sub SQLInq() 

    'Database Information 
    Dim connection As String = "Data Source=" & _Compression.path 
    Dim SQLConn As New SQLiteConnection(connection) 
    Dim SQLcmd As New SQLiteCommand(SQLConn) 
    Dim SQLdr As SQLiteDataReader 

    'Connect to Database 
    SQLConn.Open() 
    SQLcmd.Connection = SQLConn 

    'Run query 
    SQLcmd.CommandText = "Select * FROM FsFileVersion WHERE FileDescription_LTH = 'filea' LIMIT 1;" 
    SQLdr = SQLcmd.ExecuteReader() 
    While SQLdr.Read() 
     fileaVrsn = (SQLdr.GetString(SQLdr.GetOrdinal("FileVersion_LTH"))) 
    End While 
    SQLdr.Close() 

    'Run query 
    SQLcmd.CommandText = "Select * FROM FsFileVersion WHERE FileDescription_LTH = 'fileb' LIMIT 1;" 
    SQLdr = SQLcmd.ExecuteReader() 
    While SQLdr.Read() 
     filebVrsn = (SQLdr.GetString(SQLdr.GetOrdinal("FileVersion_LTH"))) 
    End While 
    SQLdr.Close() 

    'Close connection 
    SQLConn.Close() 

    'Revert cursor wait to arror 
    Application.Current.MainWindow.Cursor = Cursors.Arrow 
End Sub 
+0

不知道你的問題是什麼。如果它鎖定了UI,那麼是的,使用BackgroundWorker。 – LarsTech

+0

@LarsTech有沒有更好的方法來解決這個問題?我應該使用後臺工作來運行sql查詢嗎?我正在運行多個SQLiteCommand.ExecuteReader實例,是否可以避免這種情況?我想最大的問題是可以在一個執行讀取器中運行多個命令,而不是多個執行讀取器? – GamerJ5

+0

不知道我明白爲什麼有多個實例會出錯。你能避免它嗎?當然。爲連接,命令和讀者使用「使用...最終使用」格式。 – LarsTech

回答

1

如果你是唯一一個記錄(LIMIT 1),只有一列(FileVersion_LTH)很感興趣,那麼你可以刪除ExecuteReader,並只使用ExecuteScalar

Dim connection As String = "Data Source=" & _Compression.path 
Using SQLConn = New SQLiteConnection(connection) 
Using SQLcmd = New SQLiteCommand(SQLConn) 
    SQLConn.Open() 
    SQLcmd.CommandText = "Select FileVersion_LTH FROM FsFileVersion " & _ 
         "WHERE FileDescription_LTH = 'filea' LIMIT 1;" 
    Dim result = SQLcmd.ExecuteScalar() 
    if result IsNot Nothing Then 
     fileaVrsn = result.ToString() 
    End if 

    ... repeat for 'fileb' 
End Using 
End Using 

然而我不確定這是否是一項性能改進。畢竟,你的代碼似乎並沒有那麼糟糕。只要記住使用using statement

編輯另一個可能的改進是再次使用SQLiteDataReader,但在執行只需一個電話到數據庫

.... SQLcmd.CommandText =「選擇FileVersion_LTH FROM FsFileVersion」 & _ 「WHERE FileDescription_LTH = 'FILEA' OR」 & _ 「FileDescription_LTH = 'FILEB'」 & _ 「ORDER BY FileDescription_LTH」 使用SQLiteDataReader讀者= SQLcmd.ExecuteReader() 如果reader.Read()然後 fileaVrsn =閱讀器(0)的ToString() 如果reader.Read()然後 filebVrsn =閱讀器(0)的ToString() 結束如果 結束如果結束 使用 .. 。

這第二種方法可能是一種進步,但只有在LIMIT 1是不是真的需要

+0

良好的信息和絕對的追求。結果是從第一列向我提供信息,而不是從我在當前代碼中指定的列作爲FileVersion_LTH。 *編輯* Nevermind,注意到你對查詢字符串所做的更改。謝謝! – GamerJ5

+0

另一個可能的改進是再次使用SQLiteDataReader,但只對數據庫執行一次調用。我會更新答案 – Steve

0

對不起,我不知道的SQLite,但SQL Server和Oracle允許你通過puting一次得到多個數據表是可行的「 ;」在你的SELECT語句之間。 IE,「選擇*從X;選擇*從Y」。如果您使用數據適配器來填充數據集,它將在那裏創建2個表格。 (SQL Server還允許VBCRLF或Environment.NewLine)也許你可以做一些測試或搜索,看看sqlite是否也是如此。

其次,我也做了很多的測試,如果你正在使用DataReader返回的每一條記錄,它是通常稍快只使用一個DataAdapter和填充的DataTable。如果您沒有閱讀讀者中的每條記錄,則應重新評估SQL的WHERE子句。