将数据从sqlite表行复制到虚拟表行

问题描述 投票:0回答:1

我是 SQLite 新手,在使用 VB 编写的搜索例程时遇到问题。我有一个存储人员的表(姓名、出生日期、地址、电话号码、描述等)。我的搜索例程创建一个虚拟表(使用 fts5 模块),它具有与我的 Person 表相同的列。

假设用户想按性别和描述进行搜索。我通过找到性别匹配的每个人来开始搜索。然后我将把搜索结果放入一个虚拟表中,然后可以在该表中搜索具有匹配描述的任何人。

我有它创建虚拟表并找到具有匹配性别的每个人的位置,但我无法将这些搜索结果放入虚拟表中。我想我可以逐列复制数据,但认为可能有更简单的方法?

以下是我的代码。

Try
    'opens the database connection
    If (OpenDBConn() = False) Then
        Exit Sub
    End If

    sqliteExecCmd = GlobalVar.dbConn.CreateCommand()
    sqliteExecCmd.CommandText = "**THE COMMAND THAT FINDS EVERYONE BASED ON INITIAL SEARCH**"

    sqliteReader = sqliteExecCmd.ExecuteReader()
    sqliteExecCmd.Dispose() 'disposes of read command after it has been used

    Using sqliteReader
        While sqliteReader.Read
            'THIS IS WHERE I NEED TO PLACE ANY LOCATED RECORD(S) INTO THE VIRTUAL TABLE
        End While
    End Using

    sqliteReader.Close() 'closes reader
Catch ex As Exception
    'closes connection if it is left open
    If (GlobalVar.dbConn.State = ConnectionState.Open) Then
        CloseDBConn() 'closes the db connection
    End If

    DisplayError(ex.ToString, "SearchNoc")
End Try

CloseDBConn() 'closes the db connection
vb.net sqlite
1个回答
0
投票

实际上,在少数情况下,您将并且需要查询/过滤您“已经”从 SQLite 中提取的数据。

但是,.net 中的任何简单查询几乎总是可以作为“内存中”表返回,并且您可以过滤这些结果。然而,在大多数情况下,最好对数据库重新查询。通过索引,您通常可以获得更好的性能,并且最终使用更少的内存。

所以,拿一份简单的酒店清单。我可能想按城市搜索,然后可能按酒店名称搜索(通配符 - 以字母开头)。

那么,说出这个简单的形式:

因此,在上面,我们提取了第一个数据集(城市)。

然后,我们想要过滤更多。

但是,我没有对第一次数据拉取进行过滤,因为它确实没有多大帮助。

所以,背后的代码如下所示:

Private Sub cmdSearch_Click(sender As Object, e As EventArgs) Handles cmdSearch.Click

    Dim strSQL As String =
        "SELECT ID, FirstName, LastName, City, HotelName, Description FROM tblHotels
        WHERE City Like @City And HotelName like @Hotel
        ORDER BY HotelName"

    Dim cmdSQL As New SQLite.SQLiteCommand(strSQL)
    cmdSQL.Parameters.Add("@City", DbType.String).Value = txtCity.Text & "%"
    cmdSQL.Parameters.Add("@Hotel", DbType.String).Value = txtHotel.Text & "%"

    DataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells
    DataGridView1.DataSource = MyRstP(cmdSQL)


End Sub


Public Function MyRstP(cmdSQL As SQLite.SQLiteCommand) As DataTable

    Dim rstData As New DataTable
    Using con As New SQLite.SQLiteConnection(My.Settings.Hotels)

        cmdSQL.Connection = con
        Using (cmdSQL)
            con.Open()
            rstData.Load(cmdSQL.ExecuteReader)
        End Using
    End Using

    Return rstData

End Function

现在,在上面,我只是使用了通配符(以开头),例如匹配。

但是,我想我可以重写上面的内容,并说拉取 City 的数据表,然后根据第二个条件过滤数据表 = HotelName。

如前所述,在大多数情况下,这不值得麻烦,并且使用高速数据库索引,然后再次访问数据库引擎以获得第二个条件不仅是一个很好的方法,而且经常推荐。

但是,让我们更改代码以按城市拉取,然后根据数据表中的结果进行过滤(数据表是内存中的表,对于这种情况相当方便)。

所以,现在代码变成了这样:

Dim rstData As DataTable

Private Sub cmdSearch_Click(sender As Object, e As EventArgs) Handles cmdSearch.Click

    Dim strSQL As String =
        "SELECT ID, FirstName, LastName, City, HotelName, Description FROM tblHotels
        WHERE City Like @City 
        ORDER BY HotelName"

    Dim cmdSQL As New SQLite.SQLiteCommand(strSQL)
    cmdSQL.Parameters.Add("@City", DbType.String).Value = txtCity.Text & "%"

    DataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells
    rstData = MyRstP(cmdSQL)

    DataGridView1.DataSource = rstData


End Sub



Private Sub cmdFilter_Click(sender As Object, e As EventArgs) Handles cmdFilter.Click

    rstData.DefaultView.RowFilter = $"[HotelName] Like '{txtHotel.Text}%'"

End Sub


Public Function MyRstP(cmdSQL As SQLite.SQLiteCommand) As DataTable

    Dim rstData As New DataTable
    Using con As New SQLite.SQLiteConnection(My.Settings.Hotels)

        cmdSQL.Connection = con
        Using (cmdSQL)
            con.Open()
            rstData.Load(cmdSQL.ExecuteReader)
        End Using
    End Using

    Return rstData

End Function

因此,请注意我们如何将数据表的范围限定到表单,从而针对该数据表进行过滤,并且不要再次重新拉取数据。

所以表格现在看起来像这样:

因此,可以根据我们首先从数据库中提取的数据表进行过滤。然而,在实践中,通常最好只是从数据库中重新提取并针对数据库进行过滤,因为查询系统可以使用索引,而针对内存表(数据表对象)的过滤不使用索引。

© www.soinside.com 2019 - 2024. All rights reserved.