Как выполнить два отдельных запроса из одного объекта 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 для доступа к актуальным данным.

MSDN: использование оператора (Visual Basic)

Вы можете использовать.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 будет содержать две таблицы данных: по одной для каждого запроса

Другие вопросы по тегам