C# Выполнение 3 запросов на вставку MYSQL одним нажатием кнопки - данные из текстовых полей и списка
Мне было интересно, если вы можете мне помочь. Сначала я хотел сказать, что это мое первое приложение на C#, которое я создал, поэтому, пожалуйста, примите, что мой код не идеален.
Чего я хочу достичь: моим приложением будет приложение для управления ремонтом автомобиля. У меня есть панель, на которой у меня есть несколько текстовых полей и список. Одним нажатием кнопки я хочу сделать так, чтобы данные в текстовых полях были сохранены в таблице под названием "naprawa", а данные из списка были сохранены в таблице под названием "opisynapraw". Эти таблицы связаны с FK из "naprawa", поэтому я хочу, чтобы элементы из списка при их сохранении имели FK только что созданного поля в другой таблице. (Если это имеет смысл)
Пожалуйста, смотрите таблицу настройки ниже: Направа
|--------------+----------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
|--------------+----------------+------+-----+---------+----------------+
| Nr_Naprawy | int(11) | NO | PRI | NULL | auto_increment |
| data_naprawy | date | YES | | NULL | |
| nr_rej | varchar(45) | YES | MUL | NULL | |
| Przebieg | int(15) | YES | | NULL | |
|--------------+----------------+------+-----+---------+----------------+
Данные в этой таблице:
|------------+--------------+---------+-----------|
| Nr_Naprawy | data_naprawy | nr_rej | Przebieg |
|------------+--------------+---------+-----------|
| 1 | 2018-06-20 | na06ysa | 150000 |
|------------+--------------+---------+-----------|
Таблица описания Praw:
+---------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+---------------+------+-----+---------+----------------+
| idopisynapraw | int(11) | NO | PRI | NULL | auto_increment |
| Opis_Naprawy | varchar(45) | YES | | NULL | |
| Cena | decimal(10,2) | YES | | NULL | |
| Nr_Naprawy | int(11) | YES | MUL | NULL | |
+---------------+---------------+------+-----+---------+----------------+
Пример данных, которые я хотел бы видеть в этой таблице:
|---------------+--------------+-------+-------------|
| idopisynapraw | Opis_Naprawy | Cena | Nr_Naprawy |
|---------------+--------------+-------+-------------|
| 1 | notes abcd | 30 | 1 |
|---------------+--------------+-------+-------------|
| 2 | notes cdef | 5 | 1 |
|---------------+--------------+-------+-------------|
Что я хочу, чтобы мой код делал. Когда я нажимаю кнопку "Добавить", она добавляет запись из текстовых полей в "naprawa". Затем возьмите идентификатор того, что было добавлено, и используйте его как FK для opisynapraw и добавьте его вместе с данными из listveiw в таблицу opisynapraw.
Вот мой код
private void btnDodajNaprawe_Click(object sender, EventArgs e)
{
try
{
MySqlConnection myConn3 = new MySqlConnection(MyConnection);
myConn3.Open();
string querydoajnap = "INSERT INTO naprawa (data_naprawy,nr_rej,Przebieg) VALUES('" + dtaData.Value.Date.ToString("yyyy/MM/dd") + "', '" + txtNrRej.Text + "', '" + txtPrzebieg.Text + "');";
MySqlCommand cmd = new MySqlCommand(querydoajnap, myConn3);
MySqlConnection lastidconn = new MySqlConnection(MyConnection);
lastidconn.Open();
if (cmd.ExecuteNonQuery() == 1)
{
MessageBox.Show("Dodane");
txtNrRej.Text = string.Empty;
txtPrzebieg.Text = string.Empty;
}
else
{
MessageBox.Show("Blad");
}
String LastIDnapr = "select LAST_INSERT_ID();";
MySqlCommand cmd1 = new MySqlCommand(LastIDnapr, lastidconn);
MySqlDataReader IDRead = cmd1.ExecuteReader();
int idnumber = 0;
while (IDRead.Read())
{
idnumber = IDRead.GetInt32(0);
}
MySqlCommand cmd2 = myConn3.CreateCommand();
foreach (ListViewItem item in listView1.Items)
{
// opisynapraw(Opis_Naprawy,Cena,Nr_Naprawy) VALUES (@val1 , @val2, '" + idnumber + "');";
cmd2.Parameters.AddWithValue("@val1",item.Text);
cmd2.Parameters.AddWithValue("@val2",item.SubItems[1].Text);
cmd2.CommandText = "INSERT INTO opisynapraw(Opis_Naprawy,Cena,Nr_Naprawy) VALUES (@val1 , @val2, '" + idnumber + "');";
cmd2.ExecuteNonQuery();
}
lastidconn.Close();
myConn3.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Когда я выполняю приведенный выше код, он работает для добавления данных в таблицу "Naprawa", но я думаю, что он не будет использовать последний использованный идентификатор для связи с таблицей "opisynapraw", что приводит к следующей ошибке.
По какой-то причине мне нужны некоторые точки повторения для публикации изображений... Я напишу ниже, какое сообщение об ошибке я имею
Невозможно добавить или обновить дочернюю строку; сбой внешнего ключа ('cars','opisynapraw', CONSTRAINT 'Nr_Naprawy'FOREIGN Key ('Nr_Naprawy') ССЫЛКИ'naprawa'('Nr_Naprawy') ON УДАЛИТЬ НЕТ ДЕЙСТВИЙ ОБ ОБНОВЛЕНИИ НЕТ ДЕЙСТВИЙ)
Я был бы очень признателен за любую помощь в разрешении этой тайны.
Заранее спасибо
Rogupl
2 ответа
Вам нужно INSERT
в Naprawa, чтобы вернуть вам автоматически сгенерированное значение в том же запросе. Добавьте это в конец вашего оператора вставки, после ;
SELECT LAST_INSERT_ID();
Затем, чтобы получить его обратно, измените ExecuteNonQuery
в ExecuteScalar
- возвращаемое значение будет тем значением, которое вам нужно - оно возвращает его как объект, поэтому либо приведите его, либо System.Convert
Это. (Это требует, чтобы вы удалили свой чек, что он вставил 1 строку; но имейте в виду, что он выдаст исключение, если он потерпит неудачу.)
Теперь удалите код, относящийся к LastIDnapr
запрос, он должен работать нормально.
Дополнительные советы:
- Ваш код уязвим для атак с использованием SQL-инъекций: используйте параметры SQL вместо конкатенации строк для создания запроса.
- MySqlConnection, MySqlCommand и MySqlDataReader все IDisposable, поэтому каждый должен быть в
using
блок. - Эти соединения подключаются к одной базе данных, поэтому убедитесь, что они не перекрываются. Это будет очевидно, как только вы используете
using
блоки. - Посмотрите, можем ли мы прекратить использовать AddWithValue
Вы всегда должны использовать SqlCommand и его параметры из-за опасного кода внедрения SQL. Также хорошей идеей является создание класса обработчика базы данных, который будет обрабатывать все эти вещи.
Но давайте вернемся к вашей проблеме, я твердо верю, что вы пытаетесь вставить id в таблицу opisynapraw, которой нет в table naprawa как id. Пожалуйста, проверьте, какой идентификатор вы получаете, что вы пытаетесь вставить, и подтвердите его данными базы данных.