VB.NET: Обновление базы данных MySQL из (CheckedListBox-ComboBox)
Я сделал форму, которая должна получить данные о посещаемости для определенного сеанса. Используемые элементы:
1- CheckedListBox
2- Combobox: CB_Students
3- кнопка: обновить
Моя таблица Студент, которая содержит код | Имя | Фамилия | Day1| Day2| Day3| Day4| День 5, где Дни имеют тип tinyint, ссылаясь на Присутствие или Отсутствие.
Я хочу, чтобы пользователь проверял имена студентов из CheckedListBox, поэтому я заполнил CheckedListBox конкатенацией Имен и Фамилий, каждый элемент отображал полное имя.
Поскольку CheckedListBox косвенно создается записями базы данных, я полагаю, что не могу напрямую подключить его к базе данных, поэтому я создал скрытый ComboBox со значениями Code, соответствующими каждому ученику, показанному в CheckedListBox.
Например, моя таблица учеников выглядит так:
Код | F_Name | L_Name
1 | F1 | L1
2 | F2 | L2
CheckedListBox содержит: F1 L1 и F2 L2, а ComboBox содержит 1 и 2.
Номер дня также находится во время загрузки формы и сохраняется как открытая переменная Inquiry.
Ниже мой код для кнопки обновления:
Dim j, S As Integer
sqlstr = "UPDATE Student SET Day'" & Inquiry & "'=@field1 WHERE Code='" & CB_Students.Items.Item(j) & "'"
DBCmd = New MySql.Data.MySqlClient.MySqlCommand(sqlstr, DBConn)
With DBCmd
For j = 0 To CheckedListBox1.Items.Count - 1
S = CheckedListBox1.GetItemCheckState(j)
If S = 1 Then
.Parameters.AddWithValue("@field1", 1)
ElseIf S = 0 Then
.Parameters.AddWithValue("@field1", 0)
End If
Next j
End With
DBCmd.ExecuteNonQuery()
DBCmd.Dispose()
Однако во время выполнения я получаю сообщение об ошибке: "Параметр @field1 уже определен".
Как мне справиться с этой проблемой? Кроме того, правильно ли используется оператор CB_Students.Items.Item(j), чтобы дать моей строке sql код студента в ComboBox?
Обновление 1:
Запрос - это целое число. Я также попробовал следующий код:
For j = 0 To CheckedListBox1.Items.Count - 1
S = CheckedListBox1.GetItemCheckState(j)
If S = 1 Then
With DBCmd
.Parameters.AddWithValue("@field1", 1)
.ExecuteNonQuery()
.Dispose()
End With
ElseIf S = 0 Then
With DBCmd
.Parameters.AddWithValue("@field1", 0)
.ExecuteNonQuery()
.Dispose()
End With
End If
Next j
Но опять же, как и в моем ответе на Never_Mind, я получаю следующую ошибку в первой строке DBCmd.ExecuteNonQuery(): "У вас есть ошибка в вашем синтаксисе SQL; проверьте правильность синтаксиса в руководстве, соответствующем вашей версии сервера MySQL для используйте рядом с ''4' =1 WHERE Code='6'' в строке 1".
Значения кажутся правильными. Номер дня - 4, поле 1 - 1, код - 6. Я не вижу, в чем проблема.
Обновление 2:
Ниже приведен код для заполнения CheckedListBox и ComboBox, который находится в форме загрузки. C_Code - это код класса, еще одно поле в таблице учеников. ClassID - это открытая целочисленная переменная, сохраненная в предыдущей форме. Эта форма отображается с использованием метода.ShowDialog.
sqlstr = "SELECT * FROM Student WHERE C_Code = '" & ClassID & "'"
DBCmd = New MySql.Data.MySqlClient.MySqlCommand(sqlstr, DBConn)
DBDR = DBCmd.ExecuteReader
While (DBDR.Read())
Std_Name = DBDR("F_Name") & " " & DBDR("L_Name")
CheckedListBox1.Items.Add(Std_Name)
CB_Students.Items.Add(DBDR("Code"))
End While
DBCmd.Dispose()
DBDR.Close()
Кроме того, код является целым числом.
Обновление 3:
Я изменил тип запроса в String и удалил одинарные кавычки.
Во всяком случае, я думал, может быть, я мог бы сделать разные номера полей. Что-то вроде этого:
Dim j, S, k As Integer
sqlstr = "UPDATE Student SET D" & Inquiry & " =@field" & k & " WHERE Code='" & CB_Students.Items.Item(j) & "' "
DBCmd = New MySql.Data.MySqlClient.MySqlCommand(sqlstr, DBConn)
For j = 0 To CheckedListBox1.Items.Count - 1
For k = 1 To CheckedListBox1.Items.Count
S = CheckedListBox1.GetItemCheckState(j)
If S = 1 Then
With DBCmd
.Parameters.AddWithValue("@field" & k, 1)
.ExecuteNonQuery()
.Dispose()
End With
ElseIf S = 0 Then
With DBCmd
.Parameters.AddWithValue("@field" & k, 0)
.ExecuteNonQuery()
.Dispose()
End With
End If
Next k
Next j
Но это не работает. Я думаю, должно быть что-то не так с тем, как я объединил @field и k при добавлении через команду. Как я могу заставить его работать?
Буду очень признателен за помощь!
3 ответа
Просто понял ответ. Поскольку мы не можем воссоздать @field1, мы воссоздаем строку sql (все это), помещая ее в цикл.
For j = 0 To CheckedListBox1.Items.Count - 1
S = CheckedListBox1.GetItemCheckState(j)
sqlstr = "UPDATE Student SET D" & Inquiry & " =@field1 WHERE Code='" & CB_Students.Items.Item(j) & "' "
DBCmd = New MySql.Data.MySqlClient.MySqlCommand(sqlstr, DBConn)
If S = 1 Then
With DBCmd
.Parameters.AddWithValue("@field1", 1)
.ExecuteNonQuery()
.Dispose()
End With
ElseIf S = 0 Then
With DBCmd
.Parameters.AddWithValue("@field1", 0)
.ExecuteNonQuery()
.Dispose()
End With
End If
Next j
Этот был довольно жестким! Но, черт возьми, это легко, когда это решено, а?
Попробуй это
With DBCmd
For j = 0 To CheckedListBox1.Items.Count - 1
S = CheckedListBox1.GetItemCheckState(j)
If S = 1 Then
.Parameters.AddWithValue("@field1", 1)
.ExecuteNonQuery()
ElseIf S = 0 Then
.Parameters.AddWithValue("@field1", 0)
.ExecuteNonQuery()
End If
Next
End With
Сначала удалите одиночную кавычку из строки Inquiry, чтобы объединить прогрессив поля со словом день. ВНИМАНИЕ. Я полагаю, что вы имеете полный контроль над значением переменной Inquiry и проверяете, является ли она действительным числом, прежде чем объединять слово Day
Второй Определите ваш параметр только один раз за пределами цикла с фиктивным значением, затем внутри цикла установите значение в состояние текущего элемента и выполните запрос
Третье Использование параметра также для значения кода
j = 0 ' you should initialize this variable to a valid index inside the items collection of the combo'
sqlstr = "UPDATE Student SET Day" & Inquiry & "=@field1 WHERE Code=@code"
DBCmd = New MySql.Data.MySqlClient.MySqlCommand(sqlstr, DBConn)
With DBCmd
.Parameters.AddWithValue("@field1", 0)
.Parameters.AddWithValue("@code", Convert.ToInt32(CB_Students.Items(j)))
For j = 0 To CheckedListBox1.Items.Count - 1
S = if(CheckedListBox1.GetItemCheckState(j) = CheckState.Checked, 1, 0)
.Parameters("@field1").Value = S
.ExecuteNonQuery()
Next j
End With
Этот подход не очень эффективен, потому что команда обновления выполняется для каждого элемента дня (проверено или нет), но для устранения этой неэффективности потребуется полное переписывание этого кода.
Что касается использования элементов комбинированного списка, я думаю, что вы должны использовать свойство SelectedValue, но это зависит от того, как вы заполнили комбо и какое значение присваивается свойству ValueMember и какой тип данных является code
поле базы данных