0

我需要知道我有 3 个表,其中一个带有会话标记,主键会话 id,另一个表学生,学生 id 作为主键,第三个表数据,学生 id 和会话 id 作为外键。现在我需要在网格视图中更新每个学生的分数,以便将分数存储在会话分数表中。我正在使用这个查询

        string hourly1;
        string hourly2;
        string student_id;

        for (int i = 0; i < this.dataGridView1.Rows.Count - 1; i++)
        {
            hourly1 = dataGridView1[1,i].Value.ToString();
            hourly2 = dataGridView1[2,i].Value.ToString();
            student_id = Convert.ToString(dataGridView1[3, i].Value);

            SqlCommand cmd = new SqlCommand("UPDATE SessionalMarks  SET " +
            "SessionalMarks.Hourly1Marks = '" + hourly1 + "'," + "SessionalMarks.Hourly2Marks = '" + hourly2 + "'from Student,DATA  where Student.StudentId=DATA.StudentId AND Student.StudentId='" + student_id + "'", conn);

            conn.Open();
            cmd.ExecuteNonQuery();
            conn.Close();

但是此查询在需要更新放置在网格视图中的标记的每一行中添加相同的标记,我认为 where 子句中存在问题,请有人帮助我。

4

1 回答 1

1

非常不清楚您的 SQL 模式是什么样的,但是在您的更新语句中,之后的所有内容FROM都没有用于任何目的。您的WHERE子句没有提及SessionalMarks,因此每次循环遍历您的for循环时,您都会更新该表中的所有行。

如果您发布这三个表的 SQL 架构,它可能有助于我们了解您的数据的形状并帮助您编写更好的查询。按照您描述的方式,听起来DATA表格应该包含每个学生的分数,但您显然已经将该数据放入SessionalMarks表格中。

但是,除了您提到的问题之外,您的代码还有一些问题:

  • 您通过将字符串连接在一起来编写 SQL 查询,看起来这些字符串可能来自用户。这会使您面临 SQL 注入攻击,或者至少如果用户键入'您的程序将出现错误行为。

  • 您重复打开和关闭数据库连接,而不是打开一次并在完成后关闭它。

要解决这些问题,您可能应该 (a) 使用参数化 SQL 查询,以及 (b) 在循环外打开和关闭数据库连接。

这并不完美,但它是一个开始:

// this query needs to be fixed
string query = @"UPDATE SessionalMarks 
                SET SessionalMarks.Hourly1Marks = @hourly1
                   ,SessionalMarks.Hourly2Marks = @hourly2
                FROM Student,DATA
                WHERE Student.StudentId = DATA.StudentId
                AND Student.StudentId = @studentid";

// Make sure we dispose of the SqlCommand when we're finished with it
using (SqlCommand cmd = new SqlCommand(query, conn))
{
    // Create my three parameters, don't need a value yet
    // Need to make sure we have the right SqlDbType specified
    cmd.Parameters.Add( new SqlParameter("@hourly1", SqlDbType.Decimal) );
    cmd.Parameters.Add( new SqlParameter("@hourly2", SqlDbType.Decimal) );
    cmd.Parameters.Add( new SqlParameter("@studentid", SqlDbType.Int) );

    conn.Open();

    try
    {
        // For each row in our DataGridView
        // We could also use foreach(DataGridViewRow row in dataGridView1.Rows)
        for (int i = 0; i < this.dataGridView1.Rows.Count - 1; i++)
        {
            // Fill in our parameters with our values
            cmd.Parameters[0].Value = dataGridView1[1,i].Value.ToString();
            cmd.Parameters[1].Value = dataGridView1[2,i].Value.ToString();
            cmd.Parameters[2].Value = Convert.ToString(dataGridView1[3, i].Value);

            cmd.ExecuteNonQuery();
        }
    }
    finally
    {
        // Close our database connection even if cmd.ExecuteNonQuery() throws
        conn.Close();
    }
}
于 2012-05-13T16:50:20.373 回答