Как выполнить два отдельных запроса из одного объекта DBCommand?
У меня есть следующий код, который пытается получить записи из двух разных таблиц, а затем добавить их в конкретные списки. Работает только первый запрос, а второй игнорируется.
Try
sqlConn = New MySqlConnection
connStr = New String("Server = localhost; Database = gen_database; Uid = root; Pwd =")
sqlConn.ConnectionString = connStr
myCommand = New MySqlCommand("Select DevCompanyName from developer_name_table; Select DevType from development_type_table")
myCommand.CommandType = CommandType.Text
myCommand.Connection = sqlConn
ComboBox1.Items.Clear()
sqlConn.Open()
MsgBox("Connection Open.")
dR = myCommand.ExecuteReader()
Do While dR.Read()
ComboBox1.Items.Add(dR("DevCompanyName"))
ComboBox2.Items.Add(dR("DevType")) 'Error shows here Could not find specified column in results: DevType
Loop
Catch ex As MySqlException
MsgBox(ex.ToString)
Finally
dR.Close()
sqlConn.Close()
End Try
Я могу придумать другой способ - сделать это в нескольких запросах, но можно ли упростить код до чего-то подобного?
2 ответа
Используя DBDataReader
при 2 запросах выполняется только первый, потому что нет способа указать, из какой таблицы / запроса поступает каждый прочитанный элемент. Ваш цикл "двойного чтения", похоже, предполагает, что они будут возвращены одновременно (а не один запрос за другим - так же, как они отправляются в DBCOmmand); если бы это работало таким образом, то оно не получилось бы, если бы в каждой таблице не было одинакового количества строк.
С помощью DataTables
дает вам возможность просто связать результат с вашими комбинациями, а не копировать в них данные:
Dim SQL = "SELECT * FROM Sample; SELECT * FROM Simple"
Dim ds As New DataSet
Using dbcon As New MySqlConnection(MySQLConnStr),
cmd As New MySqlCommand(SQL, dbcon)
dbcon.Open()
Dim da As New MySqlDataAdapter(cmd)
da.Fill(ds)
End Using
' debug results
Console.WriteLine(ds.Tables.Count)
Console.WriteLine(ds.Tables(0).Rows.Count)
Console.WriteLine(ds.Tables(1).Rows.Count)
Если я посмотрю на окно вывода, оно будет печатать 2
(таблицы), 10000
(строки в T(0)) и 6
(строки в T(1)). Не все DBProviders имеют эту возможность. Access, например, захлебнется строкой SQL. Другие изменения в том, как ваш код составлен:
- DBConnections и объекты DBCommand должны быть расположены. Они распределяют ресурсы, поэтому их необходимо создавать, использовать и утилизировать для освобождения этих ресурсов.
Using
Блок делает это для нас: целевые объекты создаются в начале, закрываются и располагаются вEnd Using
,- Код выше складывает или объединяет 2 таких блока.
Код заполняет DataSet
из запроса, в этом случае создается 2 таблицы. Вместо того, чтобы копировать данные из одного контейнера в другой (например, элемент управления), вы можете использовать DataTable
как DataSource
:
cboDevName.DataSource = ds.Tables(0)
cboDevName.DisplayMember = "DevName" ' column names
cboDevName.ValueMember = "Id"
cboDevType.DataSource = ds.Tables(1)
cboDevType.DisplayMember = "DevType"
cboDevType.ValueMember = "DevCode"
Результатом будут все строки из каждой таблицы, отображаемые в соответствующем комбинированном элементе управления. Как правило, с этим типом вещи вам понадобится ID/PK и имя, которое имеет значение для пользователя в запросе. Пользователь видит понятное имя (DisplayMember
), который код может легко получить доступ к уникальному идентификатору для выбора (ValueMember
).
При использовании связанных элементов управления списком, а не с помощью SelectedIndex
и SelectedIndexChanged
событие, вы бы использовали SelectedValue
а также SelectedItem
для доступа к актуальным данным.
Вы можете использовать.net разъем (скачать здесь)
Затем вы можете установить его и добавить в свой проект (проект -> ссылки -> добавить -> просмотреть).
Наконец добавьте импорт:
Imports MySql.Data.MySqlClient
Таким образом, вы сможете использовать это:
Dim connStr as String = "Server = localhost; Database = gen_database; Uid = root; Pwd ="
Dim SqlStr as String = "Select DevCompanyName from developer_name_table; Select DevType from development_type_table"
Dim ds As DataSet = MySqlHelper.ExecuteDataset(CnStr, SqlStr)
ds будет содержать две таблицы данных: по одной для каждого запроса