Я работаю с двумя разными БД, одна из которых является SQL-сервером, а другая - MySQL.

Я пытаюсь перекрестить данные между ними. Две БД имеют одну общую ссылку на продукт. Но оба используют очень разные данные.

Например, в 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 () в конце -> «Ссылка на объект не установлена ​​на экземпляр объекта» Но я думаю, что другой код неправильный. Что я могу делать ?

0
Rwolf27 10 Май 2021 в 18:39

1 ответ

Лучший ответ

Я отделил код доступа к данным от кода пользовательского интерфейса. Это упростит сопровождение вашего приложения. В функции базы данных передаются значения, поэтому они не зависят от того, откуда эти значения. Пользовательский интерфейс не зависит от источника данных. Это может быть текстовый файл, веб-сервис или любая база данных.

Я сбросил 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

ИЗМЕНИТЬ

Чтобы типо был 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

Вы проверили синтаксис своего sql в Workbench и SSMS?

ИЗМЕНИТЬ 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
0
Mary 11 Май 2021 в 17:11