C# 运行 3 MYSQL 通过单击按钮插入查询 - 来自文本框和列表视图的数据
C# Running 3 MYSQL insert queries with single button press - Data from textboxes and listview
我想知道你是否可以帮助我。首先,我想说这是我创建的第一个 C# 应用程序,所以请接受我的代码并不完美。
我想达到的目标:
我的应用程序将是一个汽车维修管理应用程序。我有一个面板,上面有几个文本框和一个列表。单击一个按钮,我想将文本框中的数据存储在名为 'naprawa' 的 table 中,并将列表中的数据存储在名为 'opisynapraw' 的 table 中.这些 table 与来自 'naprawa' 的 FK 有关,所以我希望列表中的项目在存储时将具有其他 table 中刚刚创建的字段的 FK。 (如果有道理)
请参阅下面的 table 设置:
纳帕瓦
|--------------+----------------+------+-----+---------+----------------+
| 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 | |
|--------------+----------------+------+-----+---------+----------------+
其中的数据 table:
|------------+--------------+---------+-----------|
| Nr_Naprawy | data_naprawy | nr_rej | Przebieg |
|------------+--------------+---------+-----------|
| 1 | 2018-06-20 | na06ysa | 150000 |
|------------+--------------+---------+-----------|
Table opisynapraw:
+---------------+---------------+------+-----+---------+----------------+
| 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 | |
+---------------+---------------+------+-----+---------+----------------+
我希望在其中看到的示例数据 table:
|---------------+--------------+-------+-------------|
| idopisynapraw | Opis_Naprawy | Cena | Nr_Naprawy |
|---------------+--------------+-------+-------------|
| 1 | notes abcd | 30 | 1 |
|---------------+--------------+-------+-------------|
| 2 | notes cdef | 5 | 1 |
|---------------+--------------+-------+-------------|
我希望我的代码做什么。当我按下添加按钮时,它会将文本框中的记录添加到 'naprawa'。然后获取添加内容的 ID,并将其用作 opisynapraw 的 FK,并将其与 listveiw 中的数据一起添加到 opisynapraw table。
这是我的代码。
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);
}
}
当我执行上面的代码时,它可以将数据添加到 table 'Naprawa',但我认为它不需要最后使用的 ID 来关联 'opisynapraw' table是什么带来了以下错误。
出于某种原因,我需要一些指向 post 图片的代表...我将在下面输入我遇到的错误消息
Cannot add or update a child row; a foreign key contraint fails
('cars','opisynapraw', CONSTRAINT 'Nr_Naprawy'FOREIGN Key
('Nr_Naprawy') REFERENCES 'naprawa'('Nr_Naprawy') ON DELETE NO ACTION
ON UPDATE NO ACTION)
如果您能帮助我解开这个谜团,我将不胜感激。
提前谢谢你
罗古普
由于 sql 注入代码的危险,您应该始终使用 SqlCommand 及其参数。
此外,一个好主意是创建一个数据库处理程序 class,它将处理所有这些事情。
但让我们回到您的问题上来,我坚信您正在尝试将 id 插入 table opisynapraw,而 table naprawa 中不存在该 id。请检查您获得的 ID、您尝试插入的内容并使用数据库数据对其进行验证。
您需要 INSERT
到 Naprawa 才能在同一查询中返回自动生成的值。将其添加到插入语句的末尾,在 ;
之后
SELECT LAST_INSERT_ID();
然后要取回它,将 ExecuteNonQuery
更改为 ExecuteScalar
- 它的值 returns 将是您需要的值 - 它 returns 它作为一个对象, 所以要么投它要么 System.Convert
它。 (这要求您删除插入 1 行的检查;但请记住它会抛出失败的异常。)
现在删除与 LastIDnapr
查询相关的代码,它应该可以正常工作。
其他提示:
- 您的代码容易受到 SQL 注入攻击:使用 SQL 参数而不是字符串连接来构造查询。
- MySqlConnection、MySqlCommand 和 MySqlDataReader 都是 IDisposable,所以每个都应该在一个
using
块中。
- 这些连接连接到同一个数据库,因此请确保它们不重叠。一旦你使用
using
块,这将是显而易见的。
- 看看can we stop using AddWithValue
我想知道你是否可以帮助我。首先,我想说这是我创建的第一个 C# 应用程序,所以请接受我的代码并不完美。
我想达到的目标: 我的应用程序将是一个汽车维修管理应用程序。我有一个面板,上面有几个文本框和一个列表。单击一个按钮,我想将文本框中的数据存储在名为 'naprawa' 的 table 中,并将列表中的数据存储在名为 'opisynapraw' 的 table 中.这些 table 与来自 'naprawa' 的 FK 有关,所以我希望列表中的项目在存储时将具有其他 table 中刚刚创建的字段的 FK。 (如果有道理)
请参阅下面的 table 设置: 纳帕瓦
|--------------+----------------+------+-----+---------+----------------+
| 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 | |
|--------------+----------------+------+-----+---------+----------------+
其中的数据 table:
|------------+--------------+---------+-----------|
| Nr_Naprawy | data_naprawy | nr_rej | Przebieg |
|------------+--------------+---------+-----------|
| 1 | 2018-06-20 | na06ysa | 150000 |
|------------+--------------+---------+-----------|
Table opisynapraw:
+---------------+---------------+------+-----+---------+----------------+
| 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 | |
+---------------+---------------+------+-----+---------+----------------+
我希望在其中看到的示例数据 table:
|---------------+--------------+-------+-------------|
| idopisynapraw | Opis_Naprawy | Cena | Nr_Naprawy |
|---------------+--------------+-------+-------------|
| 1 | notes abcd | 30 | 1 |
|---------------+--------------+-------+-------------|
| 2 | notes cdef | 5 | 1 |
|---------------+--------------+-------+-------------|
我希望我的代码做什么。当我按下添加按钮时,它会将文本框中的记录添加到 'naprawa'。然后获取添加内容的 ID,并将其用作 opisynapraw 的 FK,并将其与 listveiw 中的数据一起添加到 opisynapraw table。
这是我的代码。
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);
}
}
当我执行上面的代码时,它可以将数据添加到 table 'Naprawa',但我认为它不需要最后使用的 ID 来关联 'opisynapraw' table是什么带来了以下错误。
出于某种原因,我需要一些指向 post 图片的代表...我将在下面输入我遇到的错误消息
Cannot add or update a child row; a foreign key contraint fails ('cars','opisynapraw', CONSTRAINT 'Nr_Naprawy'FOREIGN Key ('Nr_Naprawy') REFERENCES 'naprawa'('Nr_Naprawy') ON DELETE NO ACTION ON UPDATE NO ACTION)
如果您能帮助我解开这个谜团,我将不胜感激。
提前谢谢你
罗古普
由于 sql 注入代码的危险,您应该始终使用 SqlCommand 及其参数。 此外,一个好主意是创建一个数据库处理程序 class,它将处理所有这些事情。
但让我们回到您的问题上来,我坚信您正在尝试将 id 插入 table opisynapraw,而 table naprawa 中不存在该 id。请检查您获得的 ID、您尝试插入的内容并使用数据库数据对其进行验证。
您需要 INSERT
到 Naprawa 才能在同一查询中返回自动生成的值。将其添加到插入语句的末尾,在 ;
SELECT LAST_INSERT_ID();
然后要取回它,将 ExecuteNonQuery
更改为 ExecuteScalar
- 它的值 returns 将是您需要的值 - 它 returns 它作为一个对象, 所以要么投它要么 System.Convert
它。 (这要求您删除插入 1 行的检查;但请记住它会抛出失败的异常。)
现在删除与 LastIDnapr
查询相关的代码,它应该可以正常工作。
其他提示:
- 您的代码容易受到 SQL 注入攻击:使用 SQL 参数而不是字符串连接来构造查询。
- MySqlConnection、MySqlCommand 和 MySqlDataReader 都是 IDisposable,所以每个都应该在一个
using
块中。 - 这些连接连接到同一个数据库,因此请确保它们不重叠。一旦你使用
using
块,这将是显而易见的。 - 看看can we stop using AddWithValue