C#SqlCommands无法正常工作

时间:2018-05-06 10:25:46

标签: c# asp.net sql-server ado.net

我遇到代码无效的问题,我正在尝试填充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();
    }
}

1 个答案:

答案 0 :(得分:5)

此代码存在多个问题,遗憾的是,现有(现已删除)的答案均未提及,更不用说帮助修复了。

  • 有一个SQL注入风险marc_s警告过。
  • 所有这些命令必须在事务中。
  • 您正在使用like来获取学生ID,但是您从列表框中获取了名称 - 那么为什么不将ID作为ListBoxItem的值?
  • 在您借书之前,您必须首先确保至少有一份借用
  • 您正在吞咽异常
  • 您正在为SqlConnection使用类级变量,而SqlConnection最好用作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();
                }
            }
        }

    }
}