2012-05-13 60 views
0

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

 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子句中可以有一个人帮我出难题请。

回答

1

您的SQL模式看起来很不清楚,但在您的更新声明中,FROM之后的所有内容都没有用于任何目的。您的WHERE子句未提及SessionalMarks,因此每次循环访问for循环时,都会更新全部行。

如果您发布这三个表的SQL模式,它可能会帮助我们了解数据的形状并帮助您编写更好的查询。你描述它的方式,听起来像DATA表应该包含每个学生的标记,但你显然将该数据放在SessionalMarks表中。

然而,您的代码,除了你提到的一些问题:

  • 您撰写通过连接字符串连接在一起的SQL查询,它看起来像这些字符串可能来自用户。这会使您暴露于SQL注入攻击,或者至少如果用户输入',您的程序将表现不正确。

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

要解决这些问题,你应该(一)使用参数化的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(); 
    } 
}