从 2 个不同的数据库(MySQL 和 SQL)在 Listview 中插入值

Posted

技术标签:

【中文标题】从 2 个不同的数据库(MySQL 和 SQL)在 Listview 中插入值【英文标题】:Insert Values in Listview from 2 different DataBases (MySQL and SQL) 【发布时间】:2021-05-10 15:39:50 【问题描述】:

我正在使用 2 个不同的数据库,一个是 SQL 服务器,另一个是 mysql

我正在尝试交叉它们之间的数据。 2 DB 有一个共同的产品参考。但两者都使用非常不同的数据。

例如,在 Mysql 中,我有简单的数据,如描述、价格、类型...。 在 SQL 中,我使用了最后价格、折扣、条形码.... 但是有些产品在两个数据库中都没有数据,所以它们必须在某些字段中保持为空。 我必须将这些数据交叉到 ListView 中。

到目前为止我有这个代码:

    Private Sub button_search_Click(sender As Object, e As EventArgs) Handles button_search.Click


    '--------------------------------MySQL

    Call connect()

    Dim marca_prod As String
    Dim fam_prod As String
    Dim tipo_prod As String
    Dim sql As String

    rs = New ADODB.Recordset


    If type_1.Checked Then
        tipo_prod = "1"
    ElseIf type_2.Checked Then
        tipo_prod = "2"
    Else
        tipo_prod = ""
    End If


    If proc_desc.Checked Then
        sql = "SELECT p.referencia AS Referencia, p.descricao AS Descrição, p.tipo AS Tipo, f.nome_familia AS Familia, m.nome_marca AS Marca FROM ((produtos AS p INNER JOIN familias AS f ON p.Id_familia = f.Id_familia) INNER JOIN marcas AS m ON p.Id_marca = m.Id_marca) WHERE p.descricao LIKE '%" & Prod_input.Text & "%' AND p.tipo LIKE '" & tipo_prod & "%' "
    ElseIf proc_ref.Checked Then
        sql = "SELECT p.referencia AS Referencia, p.descricao AS Descrição, p.tipo AS Tipo, f.nome_familia AS Familia, m.nome_marca AS Marca FROM ((produtos AS p INNER JOIN familias AS f ON p.Id_familia = f.Id_familia) INNER JOIN marcas AS m ON p.Id_marca = m.Id_marca) WHERE p.referencia LIKE '%" & Prod_input.Text & "%' AND p.tipo LIKE '" & tipo_prod & "%' "
    Else
        sql = "SELECT p.referencia AS Referencia, p.descricao AS Descrição, p.tipo AS Tipo, f.nome_familia AS Familia, m.nome_marca AS Marca FROM ((produtos AS p INNER JOIN familias AS f ON p.Id_familia = f.Id_familia) INNER JOIN marcas AS m ON p.Id_marca = m.Id_marca) WHERE (p.referencia LIKE '%" & Prod_input.Text & "%' OR p.descricao LIKE '%" & Prod_input.Text & "%') AND p.tipo LIKE '" & tipo_prod & "%' "
    End If

    rs.Open(sql, conn)

    query_results.Items.Clear()

    While Not rs.EOF
        Dim lv As New ListViewItem
        lv = query_results.Items.Add(rs.Fields(0).Value)
        lv.SubItems.Add(rs.Fields(1).Value)
        lv.SubItems.Add(rs.Fields(2).Value)
        lv.SubItems.Add(rs.Fields(3).Value)
        lv.SubItems.Add(rs.Fields(4).Value)

        rs.MoveNext()
    End While


    '-----------------------------SQL

    Dim myDBCnn As SqlConnection
    Dim myDBCmd As SqlCommand
    Dim myDBReader As SqlDataReader
    myDBCnn = New SqlConnection("************")
    myDBCnn.Open()
    Dim MystrQ As String

    Dim i = 0
    While Not rs.EOF
        MystrQ = "Select stock, epcult, epcpond FROM st WHERE ref ='" & rs.Fields(0).Value & "'"
        myDBCmd = New SqlCommand(MystrQ, myDBCnn)
        myDBReader = myDBCmd.ExecuteReader
        While myDBReader.Read
            Dim lv As New ListViewItem
            lv = query_results.Items.Add(myDBReader.Item(5))
            lv.SubItems.Add(myDBReader.Item(6))
            lv.SubItems.Add(myDBReader.Item(7))
        End While
    End While

    myDBReader.Close()
        myDBCmd.Dispose()
        myDBCnn.Close()

        If query_results.Items.Count = 0 Then
        MsgBox("Não foram encontrados registos para os parametros selecionados!")

    End If

    count_label.Text = query_results.Items.Count

End Sub

目前我在最后的 myDBReader.Close() 中遇到错误 -> “对象引用未设置为对象的实例” 但我认为其他代码不正确。 我能做什么?

【问题讨论】:

【参考方案1】:

我将数据访问代码与用户界面代码分开。这将使您的应用程序更易于维护。数据库函数是传递值,因此它们不依赖于值的来源。用户界面不依赖于数据的来源。它可以是文本文件、Web 服务或任何类型的数据库。

我抛弃了 ADODB 和记录集,它们是非常古老的技术,直接使用了 ADO.net。这将需要 MySql 提供程序的导入。

Imports MySql.Data.MySqlClient

即使出现错误,Using...End Using 块也会处理关闭和释放数据库对象。

始终使用参数。 从不连接字符串来构建 sql 语句。我不得不猜测参数的数据类型。检查您的数据库并根据需要调整代码。

Private ConStrMySql As String = "Your connection string"
Private ConStrSql As String = "Your connection string"

Private Sub button_search_Click(sender As Object, e As EventArgs) Handles button_search.Click
    Dim tipo_prod As String
    If type_1.Checked Then
        tipo_prod = "1"
    ElseIf type_2.Checked Then
        tipo_prod = "2"
    Else
        tipo_prod = ""
    End If
    Dim dt = GetMySqlData(proc_desc.Checked, proc_ref.Checked, Prod_input.Text, tipo_prod)
    query_results.Items.Clear()
    For Each row As DataRow In dt.Rows
        Dim lv As New ListViewItem
        lv.Text = row(0).ToString
        lv.SubItems.Add(row(1).ToString)
        lv.SubItems.Add(row(2).ToString)
        lv.SubItems.Add(row(3).ToString)
        lv.SubItems.Add(row(4).ToString)
        Dim dt2 = GetSqlData(row(0).ToString)
        lv.SubItems.Add(dt2.Rows(0)(0).ToString)
        lv.SubItems.Add(dt2.Rows(0)(1).ToString)
        lv.SubItems.Add(dt2.Rows(0)(2).ToString)
        query_results.Items.Add(lv)
    Next
    If query_results.Items.Count = 0 Then
        MsgBox("Não foram encontrados registos para os parametros selecionados!")
    End If
    count_label.Text = query_results.Items.Count.ToString
End Sub

Private Function GetMySqlData(ProcDesc As Boolean, ProcRef As Boolean, ProdInput As String, tipo As String) As DataTable
    Dim sql = "SELECT p.referencia AS Referencia, p.descricao AS Descrição, p.tipo AS Tipo, f.nome_familia AS Familia, m.nome_marca AS Marca FROM ((produtos AS p INNER JOIN familias AS f ON p.Id_familia = f.Id_familia) INNER JOIN marcas AS m ON p.Id_marca = m.Id_marca) "
    If ProcDesc Then
        sql &= "WHERE p.descricao Like @Prod AND p.tipo LIKE @Type;"
    ElseIf ProcRef Then
        sql &= "WHERE p.referencia LIKE @Prod AND p.tipo LIKE @Type;"
    Else
        sql &= "WHERE (p.referencia LIKE @Prod OR p.descricao LIKE @Prod) AND p.tipo LIKE @Type;"
    End If
    Dim dt As New DataTable
    Using conn As New MySqlConnection(ConStrMySql),
            cmd As New MySqlCommand(sql, conn)
        cmd.Parameters.Add("@Prod", MySqlDbType.VarChar).Value = "%" & ProdInput & "%"
        cmd.Parameters.Add("@Type", MySqlDbType.VarChar).Value = tipo & "%"
        conn.Open()
        Using reader = cmd.ExecuteReader
            dt.Load(reader)
        End Using
    End Using
    Return dt
End Function

Private Function GetSqlData(Ref As String) As DataTable
    Dim dt As New DataTable
    Using conn As New SqlConnection(ConStrSql),
            cmd As New SqlCommand("Select stock, epcult, epcpond FROM st WHERE ref = @Ref", conn)
        cmd.Parameters.Add("@Ref", SqlDbType.VarChar).Value = Ref
        conn.Open()
        Using reader = cmd.ExecuteReader
            dt.Load(reader)
        End Using
    End Using
    Return dt
End Function

编辑

要使tipo 成为Int16(vb.net 中的短),您需要做的不仅仅是更改参数的数据类型。

更正tipo_prod的值设置。

    Dim tipo_prod As Short
    If type_1.Checked Then
        tipo_prod = 1
    ElseIf type_2.Checked Then
        tipo_prod = 2
    Else
        tipo_prod = 0
    End If

更正MySql函数的签名。

    Private Function GetMySqlData(ProcDesc As Boolean, ProcRef As Boolean, ProdInput As String, tipo As Short) As DataTable

更正sql语句。一个数字“喜欢”另一个数字可能意味着什么?

    If ProcDesc Then
        sql &= "WHERE p.descricao Like @Prod AND p.tipo = @Type;"
    ElseIf ProcRef Then
        sql &= "WHERE p.referencia LIKE @Prod AND p.tipo = @Type;"
    Else
        sql &= "WHERE (p.referencia LIKE @Prod OR p.descricao LIKE @Prod) AND p.tipo = @Type;"
    End If

你检查过你在 Workbench 和 SSMS 中的 sql 语法吗?

编辑 2

如果 SQL Server 数据库中没有匹配的数据,则忽略它。

    For Each row As DataRow In dt.Rows
        Dim lv As New ListViewItem
        lv.Text = row(0).ToString
        lv.SubItems.Add(row(1).ToString)
        lv.SubItems.Add(row(2).ToString)
        lv.SubItems.Add(row(3).ToString)
        lv.SubItems.Add(row(4).ToString)
        Dim dt2 = GetSqlData(row(0).ToString)
        If dt2.Rows.Count > 0 Then
            lv.SubItems.Add(dt2.Rows(0)(0).ToString)
            lv.SubItems.Add(dt2.Rows(0)(1).ToString)
            lv.SubItems.Add(dt2.Rows(0)(2).ToString)
        End If
        query_results.Items.Add(lv)
    Next

【讨论】:

您好,谢谢您的详细解答。我在Using reader = cmd.ExecuteReader 中收到错误,因为输入字符串的格式不正确。我知道你警告过我数据库中的数据类型,所以我将 ProdInput 设为 Varchar,将 Tipo 设为 Int16。在数据库中,它们分别是 varchar 和 Integer。我更改了代码中的所有数据类型以匹配,但我得到了同样的错误。我认为问题在于 SQL 字符串没有得到@Prod 和@Type 的值,它们按照我写的那样去,所以没有价值。 所以问题出在我的脚本上,但我更正了问题。但是,当 sql DB 中不存在产品时,我该如何处理?因为我得到了一个错误。 @Rwolf27 我在 EDIT 中处理了您的第一条评论。第二条评论见EDIT 2

以上是关于从 2 个不同的数据库(MySQL 和 SQL)在 Listview 中插入值的主要内容,如果未能解决你的问题,请参考以下文章

是否可以从具有 SQL 和 mySql 中的数据库的内部连接中获取不同数据库的信息?

mysql:只用一条sql语句,如何查出一个表里,不同条件对应的数据条数

如何从 SQL Server 中包含多行数据的 2 个表中选择 4 个不同的值?

数据库优化之mysql

如何从 2 个不同的 SQL Server 获取数据

hive和mysql的区别是啥?