【发布时间】:2017-11-21 04:31:11
【问题描述】:
我有一个按钮,单击该按钮可将文本框和组合框字段中的数据插入数据库表中,但每次插入时都会给我“关闭阅读器时调用读取的无效尝试”。我怎样才能摆脱这个错误。欢迎使用优化代码的技巧,因为我知道我是个菜鸟。谢谢
private void btnSave_Click(object sender, RoutedEventArgs e)
{
try
{
SqlConnection sqlCon = new SqlConnection(@"Data Source=(localdb)\mssqllocaldb; Initial Catalog=Storagedb;");
sqlCon.Open();
string Query1 = "insert into location(Storage, Shelf, columns, rows) values(" + txtWarehouse.Text + ", " + txtShelf.Text + ", " + txtColumn.Text + ", " + txtRow.Text + ")";
SqlCommand sqlCmd = new SqlCommand(Query1, sqlCon);
SqlDataAdapter dataAdp = new SqlDataAdapter(sqlCmd);
dataAdp.SelectCommand.ExecuteNonQuery();
sqlCon.Close();
}
catch (Exception er)
{
MessageBox.Show(er.Message);
}
try
{
SqlConnection sqlCon = new SqlConnection(@"Data Source=(localdb)\mssqllocaldb; Initial Catalog=Storagedb;");
sqlCon.Open();
string Query3 = "SELECT LOCATION_ID FROM LOCATION WHERE storage='" + txtWarehouse.Text + "' AND shelf='" + txtShelf.Text + "' AND columns='"
+ txtColumn.Text + "' AND rows='" + txtRow.Text + "'";
SqlCommand sqlCmd1 = new SqlCommand(Query3, sqlCon);
SqlDataReader dr = sqlCmd1.ExecuteReader(); ;
while (dr.Read())
{
string LocationId = dr[0].ToString();
dr.Close();
string Query2 = "insert into product(SKU, nimetus, minimum, maximum, quantity,location_ID,category_ID,OrderMail_ID) values ('" + txtSku.Text + "','" + txtNimetus.Text + "', '"
+ txtMin.Text + "', '" + txtMax.Text + "', '" + txtQuan.Text + "', '" + LocationId + "', '" + (cbCat.SelectedIndex+1) + "', '" + (cbMail.SelectedIndex+1) + "')";
SqlCommand sqlCmd = new SqlCommand(Query2, sqlCon);
SqlDataAdapter dataAdp = new SqlDataAdapter(sqlCmd);
dataAdp.SelectCommand.ExecuteNonQuery();
}
sqlCon.Close();
}
catch (Exception ed)
{
MessageBox.Show(ed.Message);
}
}
【问题讨论】:
-
这里不需要DataAdapter。只需从您构建的 SqlCommand 调用 ExecuteNonQuery。
-
删除 dr.Close();行
-
“已经有一个打开的数据读取器与此命令关联,必须先关闭”是我现在得到的错误,现在没有数据插入数据库
-
您应该考虑更改处理 SQL 查询的方式。在您编写它时,它极易受到 SQL 注入攻击,任何使用您的应用程序的人都可以通过在文本框中输入脚本将整个数据库丢给您。查看 Paul 的回答 here,了解如何使用数据库参数来防止 SQL 注入。他还提供了一个很好的链接,可以帮助您更好地理解 SQL 注入。
-
您正在尝试在 while 循环中读取,但在您调用
dr.Close()的 while 循环中的第二行尝试使用调试器并开始审查您自己的代码。我还建议将选择并更新到自己的较小方法中,以使您的代码更具可读性。这有点混乱,并且在SQL Injection上也可以阅读
标签: c# sql sql-server wpf