c# - C# SqlCommands 不起作用
问题描述
我有一个代码不起作用的问题,我正在尝试填充保存在 SQL Server 上 localhost 中的数据库,但代码什么也没做:(
private void button2_Click(object sender, EventArgs e)
{
try
{
conn.Open();
if (dataGridView1.SelectedRows.Count != 0 && listBox1.SelectedIndex != -1)
{
string id = "select studentID from student where studentName like '%" + listBox1.SelectedItem.ToString() + "%'";
SqlCommand a = new SqlCommand(id, conn);
a.ExecuteNonQuery();
SqlDataReader reader = a.ExecuteReader();
string s = reader.GetString(0);
string q = "insert into Borrow values (" + dataGridView1.CurrentRow.Cells[0].Value.ToString()
+ ", " + s + " , '" + DateTime.Now + "' , Null)";
SqlCommand cmd = new SqlCommand(q, conn);
cmd.ExecuteNonQuery();
MessageBox.Show("Book is now Borrowed");
string tmp = "update Book set quantity=quantity-1 where bookID " + dataGridView1.CurrentRow.Cells[0].Value.ToString();
SqlCommand tm = new SqlCommand(tmp, conn);
}
}
catch
{
}
finally
{
conn.Close();
}
}
解决方案
此代码存在多个问题,不幸的是,现有(现已删除)答案都没有提及,更不用说帮助修复了。
- marc_s 警告过 SQL 注入风险。
- 所有这些命令都必须在一个事务中。
- 您正在使用
like
获取学生 ID,但您从列表框中获取名称 - 那么为什么不将 id 作为 ListBoxItem 的值呢? - 在你可以借书之前,你必须首先确保你至少有一本可以借
- 你正在吞咽异常
- 您正在使用类级变量 for
SqlConnection
, whileSqlConnection
最好用作 using 语句中的局部变量。 - 您正在将代码与显示混合 - 这将是不可能的,或者至少很难测试。可测试性是可维护性的一部分。
- 你的变量命名很糟糕。变量名应该是有意义的——这样当有人阅读代码时,他们可以通过阅读变量名来了解变量的含义。
- 唯一应该在
try
块内的是实际的数据库访问。异常和Try...catch
块适用于您无法在代码中测试或控制的内容。
综上所述,这里有一个稍微改进的代码版本作为起点。请尝试进一步改进它以解决我上面列出的所有(或至少大部分)问题:
private void button2_Click(object sender, EventArgs e)
{
if (dataGridView1.SelectedRows.Count != 0 && listBox1.SelectedIndex != -1)
{
using(var con = new SqlConnection(connectionString))
{
var trn = con.BeginTransaction();
var sqlGetStudentId = "select studentID from student where studentName = @studentName";
using(var cmd = new SqlCommand(sqlGetStudentId, conn))
{
cmd.Parameters.Add("@studentName", SqlDbType.VarChar).Value = listBox1.SelectedItem.ToString();
try
{
con.Open();
string studentId = cmd.ExecuteScalar()?.ToString();
if(!string.IsNullOrEmpty(studentId))
{
// Note: You must first check if there are books left to borrow!
cmd.CommandText = "update Book set quantity=quantity-1 where bookID = @BookId";
cmd.Parameters.Clear();
cmd.Parameters.Add("@BookId", SqlDbType.VarChar).Value = dataGridView1.CurrentRow.Cells[0].Value.ToString();
cmd.ExecuteNonQuery();
cmd.CommandText = "insert into Borrow (/* Alwasy specify columns list! */) values (@IAmGuessingBookId, @StudentId, GETDATE(), NULL)";
cmd.Parameters.Clear();
cmd.Parameters.Add("@IAmGuessingBookId", SqlDbType.VarChar).Value = dataGridView1.CurrentRow.Cells[0].Value.ToString();
cmd.Parameters.Add("@StudentId", SqlDbType.VarChar).Value = studentId;
cmd.ExecuteNonQuery();
trn.Commit();
}
}
catch(Exception ex)
{
// Do something with the exception!
// show an error description to the client,
// log for future analisys
trn.Rollback();
}
}
}
}
}
推荐阅读
- scala - 带有标记点的Scala多类分类
- arduino - 使用 getRXMRAWX() 对 Arduino 进行编程以输出 UBX 消息
- javascript - Fabric.js 翻转时移动多边形形状的点失败
- reactjs - 导出 react-bootstrap-table2 到 excel 或者 csv 不好
- python - 在 Python 中测试类的正确方法是什么?
- typescript - ts-expect-error 仅针对特定类型的错误
- arrays - 用逗号、空格和数字构建两个数组并打印出来
- wordpress - 包装盒中的 Woocommerce 运输产品
- sql - Firebird 如何在 ORDER BY 中使用带有子查询列的 IIF
- java - JWT getPrincipal 错误,对 Authentication 的引用不明确