如何用C#和Windows Forms将两表ID插入关联表StudentClassCombo
问题原因
你的INSERT语句语法不符合SQL规范:INSERT ... SELECT要求单条SELECT语句返回的列数与INSERT指定的插入列数完全匹配。你写的两个独立SELECT子句各返回1列,SQL不会自动将两个查询的结果拼接为两列,反而会识别为语法结构错误,因此抛出列数不匹配的异常。
解决方案
1. 修正SQL语句
将两个子查询合并为同一条SELECT语句的两个返回字段,修正后的INSERT语句如下:
INSERT INTO dbo.StudentClassCombo (ClassID, StudentID) SELECT (SELECT Id FROM dbo.Class WHERE Grade = @Grade), (SELECT Id FROM dbo.Student WHERE Name = @StudentName)
2. 完整修正后代码
private void student2class_Click(object sender, EventArgs e) { // 修正后的SQL语句 string insertCommand = @"INSERT INTO dbo.StudentClassCombo (ClassID, StudentID) SELECT (SELECT Id FROM dbo.Class WHERE Grade = @Grade), (SELECT Id FROM dbo.Student WHERE Name = @StudentName)"; using (SqlConnection connection = new SqlConnection(connectionString)) using (SqlCommand Insertcmd = new SqlCommand(insertCommand, connection)) { Insertcmd.Parameters.Add("@Grade", SqlDbType.Int); Insertcmd.Parameters.Add("@StudentName", SqlDbType.NVarChar, 50); connection.Open(); foreach (ListViewItem eachItem in StudentsList.CheckedItems) { Insertcmd.Parameters["@Grade"].Value = int.Parse(ClassNames.Text); Insertcmd.Parameters["@StudentName"].Value = eachItem.SubItems[0].Text; Insertcmd.ExecuteNonQuery(); } } // using块会自动释放连接,不需要手动调用Close() }
优化建议
- 班级下拉框绑定数据时,建议将
Class.Id作为下拉框的Value属性存储,无需通过Grade二次查询Class表,既提升性能也能避免同年级存在多个班级时查询结果出错的问题。 - 学生ListView绑定数据时,建议将
Student.Id存在ListViewItem的Tag属性中,无需通过学生姓名查询Student表,避免重名学生导致关联错误。
内容的提问来源于stack exchange,提问作者a_sid
相关产品推荐
相关产品推荐

