как использовать несколько результатов в VB.net - PullRequest
0 голосов
/ 07 ноября 2019

Мне нужно показать в 3 текстовых полях результат 3 запросов, выполненных в одном выражении.

У меня есть две таблицы с именами personal_sueldos и personal_haberes в mysql. У них обоих одинаковые столбцы. Мне нужно выбрать одну и ту же информацию из обоих в двух запросах, а третий запрос - это вычитание descuentos из haberes.
Так что я должен показать все 3 результата в 3 текстовых полях в форме VB.NET.

Код запроса в MySql:

SELECT SUM(importe) FROM personal_haberes WHERE persona_doc = 55880334 AND mes = 11 AND año = 2019;

SELECT SUM(importe) FROM personal_descuentos WHERE persona_doc = 55880334 AND mes = 11 AND año = 2019;

SELECT (SELECT SUM(importe) FROM personal_haberes WHERE persona_doc = 
55880334 AND mes = 11 AND año = 2019) -
(SELECT SUM(importe) FROM personal_descuentos WHERE persona_doc = 
55880334 AND mes = 11 AND año = 2019) as importeTotal

Код в VB.NET:

cnn.Open()
Dim Query As String
Query = "SELECT SUM(importe) as ImporteHaberes FROM personal_haberes WHERE persona_doc  = " & Module1.document & " AND mes = " & HR_DatePicker.Value.Month & " AND año = " & HR_DatePicker.Value.Month & ";" & _
"SELECT SUM(importe) as ImporteDescuentos FROM personal_descuentos WHERE persona_doc = " & Module1.document & " AND mes = " & HR_DatePicker.Value.Month & " AND año = " & HR_DatePicker.Value.Month & ";" & _
"SELECT (SELECT SUM(importe) FROM personal_haberes WHERE persona_doc    = " & Module1.document & " AND mes = " & HR_DatePicker.Value.Month & " AND año = " & HR_DatePicker.Value.Month & ";) -" & _
"(SELECT SUM(importe) FROM personal_descuentos WHERE persona_doc = " & Module1.document & " AND mes = " & HR_DatePicker.Value.Month & " AND año = " & HR_DatePicker.Value.Month & ";) AS ImporteTotal"
Dim cmd As New MySqlCommand(Query, cnn)
rdr = cmd.ExecuteReader
While rdr.Read
    Me.HR_txtHaberes.Text = rdr.Item("ImporteHaberes").ToString
    Me.HR_txtDescuentos.Text = rdr.Item("ImporteDescuentos").ToString
    Me.HR_txtTotal.Text = rdr.Item("ImporteTotal").ToString
End While
cnn.Close()

Я должен показать результат каждого запроса в текстовом поле.

Теперь VB выдает ошибку «Не удалось найти указанный столбец в результатах»

Ответы [ 2 ]

1 голос
/ 08 ноября 2019

Здесь есть лот для очистки. никогда нормально использовать конкатенацию строк для создания такого запроса, даже в обучающем коде . Это также не правильный способ управления объектом подключения.

Улучшенный шаблон (с фиксированным кодом, включая следующую проблему с результатами), выглядит следующим образом:

'Multi-line string literals are now supported
' Note: there is NO CONCATENATION here. This is a constant.
' I also consolidated the SQL to avoid worrying about separate result sets.
Dim Query As String = "
    SELECT SUM(importe) as Importe
     FROM personal_haberes
     WHERE persona_doc = @document AND mes = @mes AND año = @ano
    UNION ALL
    SELECT SUM(importe)
     FROM personal_descuentos
     WHERE persona_doc = @document AND mes = @mes AND año = @ano;"

Using cnn As New MySqlConnection("connection string here"), _
      cmd As New MySqlCommand(query, cnn)

    'Guessing at types/lengths here.
    ' Use the ACTUAL columns types and lengths from your database
    cmd.Parameters.Add("@document", MySqlDbType.VarChar, 50).Value = Module1.document
    cmd.Parameters.Add("@mes", MySqlDbType.Int32).Value = HR_DatePicker.Value.Month
    cmd.Parameters.Add("@ano", MySqlDbType.Int32).Value = HR_DatePicker.Value.Year 'This was your error

    'Wait as long as possible to call .Open()
    cnn.Open()
    Using rdr As MySqlDataReader = cmd.ExecuteReader()
        rdr.Read()
        Dim Haberes As Integer = CInt(rdr("Importe"))
        rdr.Read()
        Dim Descuentos As Integer = CInt(rdr("Importe"))

        Me.HR_txtHaberes.Text = Haberes.ToString()
        Me.HR_txtDescuentos.Text = Descuentos.ToString()
        Me.HR_txtTotal.Text = (Haberes - Descuentos).ToString() 'No need to make the database do the subtraction work.
    End Using
End Using ' This will take care of closing the connection.. even if an exception is thrown!
'The old code might have leaked open connections whenever there was an exception.
0 голосов
/ 08 ноября 2019

Давайте начнем менять ваш запрос на параметризованный. Ваш учитель сказал вам, что это не важно в вашем текущем контексте, но я категорически не согласен. Написание параметризованного запроса - это навык, который необходимо освоить как можно скорее. Часть из соображений безопасности, посмотрим, насколько ясно теперь без всех этих объединений.

Dim Query As String = "
    SELECT SUM(importe) as ImporteHaberes 
    FROM personal_haberes 
    WHERE persona_doc  = @doc AND mes = @mes AND año = @año;
    SELECT SUM(importe) as ImporteDescuentos 
    FROM personal_descuentos 
    WHERE persona_doc = @doc AND mes = @mes AND año = @año;
    SELECT  (SELECT SUM(importe) 
        FROM personal_haberes 
        WHERE persona_doc = @doc AND mes = @mes AND año = @año) -
            (SELECT SUM(importe) 
        FROM personal_descuentos 
        WHERE persona_doc = @doc AND mes = @mes AND año = @año) AS ImporteTotal"

Теперь создайте команду и добавьте три параметра
Опять посмотрите, насколько она более краткая и понятнаяи легко обнаружить проблему с Value.Month, повторяющимся также для окончательного параметра.

Dim cmd As New MySqlCommand(Query, cnn)
cmd.Parameters.Add("@doc", MySqlDbType.VarChar).Value = Module1.document
cmd.Parameters.Add("@mes", MySqlDbType.Int32).Value = HR_DatePicker.Value.Month
' ???? This should be HR_DatePicker.Value.Year ???? '
cmd.Parameters.Add("@año", MySqlDbType.Int32).Value = HR_DatePicker.Value.Month
rdr = cmd.ExecuteReader

А теперь использование NextResult. Просто запустите свой первый цикл, чтобы получить первый результат, затем перейдите ко второму результату и т. Д.

While rdr.Read()
    Me.HR_txtHaberes.Text = rdr.Item("ImporteHaberes").ToString
End While    
rdr.NextResult() 

While rdr.Read()
    Me.HR_txtDescuentos.Text = rdr.Item("ImporteDescuentos").ToString
End While
rdr.NextResult() 
While rdr.Read()
    Me.HR_txtTotal.Text = rdr.Item("ImporteTotal").ToString
End While

Учитывая тот факт, что вы возвращаете всегда одну запись для каждого запроса, вы также можете заменить whileпетля с простым

If rdr.Read() Then
    Me.HR_txtHaberes.Text = rdr.Item("ImporteHaberes").ToString
End If
rdr.NextResult() 
..... 
...