vb.netvisual-studio-2022mysql-connector

How do I run a SELECT query on a MySQL database in vb.net?


I've been using vb.net (visual studio 2022) to run INSERT and DELETE queries on a MySQL server, but now I need to run a SELECT query and get the returned values.

My code to run the INSERT query looks like this:

Public Function StoreData() As Object
    'Write the times and types to the tblparams table of the database
    Dim strS1Type As String, strS2Type As String, sM1Ts As String, sM2Ts As String, sM1Tr As String, sM2Tr As String
    Dim connectionString As String, iReturn As Boolean


    'Connection String to connect with MySQL database.
    connectionString = "server=xx.xx.xx.xx;userid=user;password=password;database=database"

    Using SQLConnection As New MySqlConnection(connectionString)
        Using sqlCommand As New MySqlCommand()
            With sqlCommand
                .CommandText = "INSERT INTO tbldata(M1Type, M1Start, M1Tr, M2Type, M2Start, M2Tr, M1SheetType, M2SheetType) VALUES(@M1Type, @M1Start, @M1Tr, @M2Type, @M2Start, @M2Tr, @M1SheetType, @M2SheetType);"
                .Connection = SQLConnection
                .CommandType = CommandType.Text
                .Parameters.AddWithValue("@M1Type", strS1Type)
                .Parameters.AddWithValue("@M1Start", sM1Ts)
                .Parameters.AddWithValue("@M1Tr", sM1Tr)
                .Parameters.AddWithValue("@M2Type", strS2Type)
                .Parameters.AddWithValue("@M2Start", sM2Ts)
                .Parameters.AddWithValue("@M2Tr", sM2Tr)
                .Parameters.AddWithValue("@M1SheetType", GlobalVariables.strM1SheetType)
                .Parameters.AddWithValue("@M2SheetType", GlobalVariables.strM2SheetType)
            End With
            Try
                SQLConnection.Open()
                sqlCommand.ExecuteNonQuery()
                iReturn = True
            Catch ex As MySqlException
                MsgBox(ex.Message.ToString)
                iReturn = False
            Finally
                SQLConnection.Close()
            End Try
        End Using
    End Using

End Function

From what I've read, having the code in the USING clauses ensures that the connections to the database are closed when it exits the USING clauses. I have tried to modify this code to return data from a SELECT query:

Public Sub RestoreData()
    'Read the start times and types from the tblparams table of the mtmdev database and load into controls
    Dim connectionString As String, iReturn As Boolean, vResult As String, i As Integer, a As Array
    'Define connection String to connect with MySQL database.
    connectionString = "server=xx.xx.xx.xx;userid=user;password=password;database=database"
    Using SQLConnection As New MySqlConnection(connectionString)
        Using sqlCommand As New MySqlCommand()
            With sqlCommand
                .CommandText = "SELECT * FROM tbldata;"
                .Connection = SQLConnection
                .CommandType = CommandType.Text
            End With
            i = 0
            Try
                SQLConnection.Open()
                 sqlCommand.ExecuteReader()
                While vResult = sqlCommand.ExecuteReader.GetValue(i)
                    MsgBox("Result is:" & vbCrLf & vResult)
                    i = i + 1
                    iReturn = True
                End While
            Catch ex As MySqlExceptionSystem
                MsgBox(ex.Message.ToString)
                iReturn = False
            Finally
                SQLConnection.Close()
            End Try
        End Using
    End Using
End Sub

But that results in the following error: System.InvalidOperationException: 'This MySqlConnection is already in use. See https://fl.vu/mysql-conn-reuse '

when it gets to the line:

While vResult = sqlCommand.ExecuteReader.GetValue(i)

Should I be using a different syntax to read the field values returned by the query?


Solution

  • You are calling ExecuteReader twice, which doesn't make sense. As any example on the web would have shown you, you call ExecuteReader and it returns a data reader, then you use that to read the data, e.g.

    Using connection As New MySqlConnection(connectionString),
          command As New MySqlCommand(query, connection)
        connection.Open()
    
        Using reader = command.ExecuteReader()
            While reader.Read()
                Console.WriteLine($"{reader.GetInt32(reader.GetOrdinal("Id"))} - {reader.GetString(reader.GetOrdinal("Name"))}")
            End While
        End Using
    End Using
    

    Read will return True if and only if there is a row to read, so that loop will read each row in the result set.