Я использовал vb.net (visual studio 2022) для запуска запросов INSERT и DELETE на сервере MySQL, но теперь мне нужно запустить запрос SELECT и получить возвращаемые значения.
Мой код для запуска запроса INSERT выглядит следующим образом:
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
Судя по тому, что я прочитал, наличие кода в предложениях USING гарантирует, что соединения с базой данных будут закрыты при выходе из предложений USING. Я попытался изменить этот код, чтобы он возвращал данные из запроса SELECT:
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
Но это приводит к следующей ошибке: System.InvalidOperationException: «Этот MySqlConnection уже используется. См. https://fl.vu/mysql-conn-reuse '
когда дело доходит до строки:
While vResult = sqlCommand.ExecuteReader.GetValue(i)
Должен ли я использовать другой синтаксис для чтения значений полей, возвращаемых запросом?
Я бы также рекомендовал указывать имена столбцов, а не использовать SELECT *
@SSS, для справки, DataTable — это средство хранения данных, а не их извлечения, и следует ли вам его использовать, зависит от того, как вы хотите использовать данные. Если вы просто хотите использовать запись данных по записи по мере ее чтения, то подойдет только устройство чтения данных. Если вы хотите иметь произвольный доступ к данным, но не сохранять какие-либо изменения, можно использовать вместе средство чтения данных и DataTable. Если вы хотите сохранить изменения, подойдет адаптер данных и DataTable.
@jmcilhinney, спрашивающий пытается загрузить каждый столбец в цикле. Я подозреваю, что DataTable больше соответствует тому, чего они пытаются достичь. ЯММВ
На самом деле у меня есть только одна строка данных, поэтому DataTable мне не нужен. Кроме того, SELECT * был нужен только для того, чтобы код работал, теперь я перечисляю имена столбцов в запросе ;-)





Вы звоните ExecuteReader дважды, что не имеет смысла. Как показал бы вам любой пример в Интернете, вы вызываете ExecuteReader, и он возвращает устройство чтения данных, затем вы используете его для чтения данных, например.
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 вернет True тогда и только тогда, когда есть строка для чтения, так что цикл будет читать каждую строку в наборе результатов.
Спасибо за этот ответ — это и эта статья stackoverflow.com/questions/50884500/…, в которой объясняется синтаксис, который мне нужен для извлечения полей, возвращаемых Execute.Reader. Я провел немало поисков, прежде чем задать этот вопрос, но было много ответов, использующих структуры, отличные от той, которую я использовал для своих запросов INSERT и DELETE. Я хотел, чтобы запросы SELECT использовали одну и ту же базовую структуру, и ваш ответ дал мне именно то, что я хотел!
Рассмотрите возможность использования
DataTableдля хранения данных о возврате stackoverflow.com/a/10845783/741136