Reputation: 19
I'm working with 2 different DB, one is an SQL server and the other is a MySQL.
I'm trying to cross the data between them. The 2 DB have one reference of product in common. But both use very different data.
For example in Mysql I have simple data like, description, price, type .... And in SQL I have Last price used, discounts, barcode .... But there are some products that don't have data in both DB, so they have to remain empty in some fields. And I Have to cross this data into a ListView.
I have this code so far:
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
At the moment I got an error in the myDBReader.Close() at the end -> "Object reference not set to an instance of an object" But i think the other code is not right. What can I do ?
Upvotes: 0
Views: 80
Reputation: 15091
I separated the data access code from the user interface code. This will make your application easier to maintain. The database functions are passed values so they are not dependent on where the values come from. The user interface is not dependent on where the data comes from. It could be a text file, a web service or any kind of database.
I dumped the ADODB and recordset which are very old technologies and used straight ADO.net. This will require an imports for the MySql provider.
Imports MySql.Data.MySqlClient
The Using...End Using
blocks handle closing and disposing database objects even if there is an error.
Always use parameters. Never concatenate strings to build sql statements. I had to guess at the datatypes for the parameters. Check your database and adjust the code as necessary.
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
EDIT
For tipo to be an Int16 (Short in vb.net) you will need to do more than just change the datatype of the parameter.
Correct the setting of the value of 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
Correct the signature of the MySql function.
Private Function GetMySqlData(ProcDesc As Boolean, ProcRef As Boolean, ProdInput As String, tipo As Short) As DataTable
Correct the sql statement. What could it possibly mean for one number to be "Like" another?
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
Have you checked the syntax of your sql in Workbench and SSMS?
EDIT 2
If there is not matching data in the SQL Server database just ignore it.
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
Upvotes: 1