我正在做一个将图书馆管理系统开发为图书馆的项目。在其中,我通过将学生的详细信息保存到数据库来注册学生。最初插入记录时,将在没有给定成员编号的情况下保存该记录。
然后,当我开始保存下一个学生的详细信息时,我收到一条错误消息:“违反了PRIMARY KEY约束。”
单击消息中的“确定”按钮并尝试再次保存数据后,我收到一条消息,提示“连接未关闭”。
尽管我尝试找到未关闭的连接,但在我的代码中找不到一个。这里是代码。
try
{
if (rbtnMale.Checked == true)
{
Gender = "Male";
}
else if (rbtnFemale.Checked == true)
{
Gender = "Female";
}
if (cmbMemNo.Visible == true)
{
String insert_query = "INSERT INTO StReg VALUES('" + cmbMemNo.Text + "','" + txtFName.Text + "','" + txtName.Text + "','" + Gender + "','" + dtpDOB.Text + "','" + txtTelNo.Text + "','" + txtSchool.Text + "','" + txtAdNo.Text + "','" + txtMom.Text + "','" + txtMomOcc.Text + "','" + txtDad.Text + "','" + txtDadOcc.Text + "')";
Con.Open();
Cmd = new SqlCommand(insert_query, Con);
Cmd.ExecuteNonQuery();
Con.Close();
MessageBox.Show("The new Student " + txtName.Text + "( S-" + cmbMemNo.Text + " ) has successfully inserted into the system!!!", "INSERTED!!!", MessageBoxButtons.OK, MessageBoxIcon.Information);
Clear();
}
else if (txtMemNo.Visible == true)
{
String insert_query = "INSERT INTO StReg VALUES('" + cmbMemNo.Text + "','" + txtFName.Text + "','" + txtName.Text + "','" + Gender + "','" + dtpDOB.Text + "','" + txtTelNo.Text + "','" + txtSchool.Text + "','" + txtAdNo.Text + "','" + txtMom.Text + "','" + txtMomOcc.Text + "','" + txtDad.Text + "','" + txtDadOcc.Text + "')";
Con.Open();
Cmd = new SqlCommand(insert_query, Con);
Cmd.ExecuteNonQuery();
Con.Close();
MessageBox.Show("The new Student " + txtName.Text + "( S-" + cmbMemNo.Text + " ) has successfully inserted into the system!!!", "INSERTED!!!", MessageBoxButtons.OK, MessageBoxIcon.Information);
Clear();
}
}
catch (Exception ex)
{
MessageBox.Show("Error while Inserting details to the Database!!!" + Environment.NewLine + ex);
}
这是我的餐桌设计。
这是我的表定义代码。
CREATE TABLE [dbo].[StReg]
(
[MemNo] VARCHAR(12) NOT NULL,
[FName] VARCHAR(MAX) NOT NULL,
[Name] VARCHAR(50) NOT NULL,
[Gender] VARCHAR(6) NOT NULL,
[DOB] DATE NOT NULL,
[TelNo] VARCHAR(10) NULL,
[School] VARCHAR(50) NOT NULL,
[AdNo] VARCHAR(10) NOT NULL,
[MomName] VARCHAR(50) NOT NULL,
[MomOcc] VARCHAR(50) NOT NULL,
[DadName] VARCHAR(50) NOT NULL,
[DadOcc] VARCHAR(50) NOT NULL,
PRIMARY KEY CLUSTERED ([MemNo] ASC)
);
无论我多么努力地发现任何错误,我仍然无法弄清楚。请帮忙!
答案 0 :(得分:2)
连接没有关闭,因为您没有关闭它。在关闭连接并打开连接之前发生了异常。像这样进行所有查询:
try
{
Con.Open();
Cmd = new SqlCommand(insert_query, Con);
Cmd.ExecuteNonQuery();
}
finally
{
Con.Close();
}
发生异常是因为您提供了非唯一的主键或根本没有提供它。 不要使用易受SQL injections语句影响的语句,而要使用SQL参数,例如:
SqlCommand cmd = new SqlCommand("select * from Customers where city = @City", conn);
SqlParameter param = new SqlParameter();
param.ParameterName = "@City";
param.Value = inputCity;
cmd.Parameters.Add(param);
答案 1 :(得分:2)
建议您将主键设置为自动增量,并且在自动生成时无需插入主键值
创建您的表格是这样的
CREATE TABLE [dbo].[StReg]
(
[MemNo] int identity(1,1) PRIMARY KEY NOT NULL,
[FName] VARCHAR(MAX) NOT NULL,
[Name] VARCHAR(50) NOT NULL,
[Gender] VARCHAR(6) NOT NULL,
[DOB] DATE NOT NULL,
[TelNo] VARCHAR(10) NULL,
[School] VARCHAR(50) NOT NULL,
[AdNo] VARCHAR(10) NOT NULL,
[MomName] VARCHAR(50) NOT NULL,
[MomOcc] VARCHAR(50) NOT NULL,
[DadName] VARCHAR(50) NOT NULL,
[DadOcc] VARCHAR(50) NOT NULL
);
例如:identity(10000,5)=>您的主键从10000开始,每次增加5。
并在不使用 cmbMemNo.Text 的情况下修改您的插入查询,因为它将自动生成唯一的ID。
String insert_query = "INSERT INTO StReg VALUES('" + txtFName.Text + "','" + txtName.Text + "','" + Gender + "','" + dtpDOB.Text + "','" + txtTelNo.Text + "','" + txtSchool.Text + "','" + txtAdNo.Text + "','" + txtMom.Text + "','" + txtMomOcc.Text + "','" + txtDad.Text + "','" + txtDadOcc.Text + "')";
关于您的第二个错误,是因为您的第一个异常发生在 Cmd.ExecuteNonQuery(); 行上,并先行执行到 catch(),然后是您的 Con.Close(); 无法执行,连接也不会关闭。您有2种选择,
第一个选项-检查连接状态,如果关闭则打开
String insert_query = "INSERT INTO StReg VALUES('" + cmbMemNo.Text + "','" + txtFName.Text + "','" + txtName.Text + "','" + Gender + "','" + dtpDOB.Text + "','" + txtTelNo.Text + "','" + txtSchool.Text + "','" + txtAdNo.Text + "','" + txtMom.Text + "','" + txtMomOcc.Text + "','" + txtDad.Text + "','" + txtDadOcc.Text + "')";
if (Con.State == System.Data.ConnectionState.Closed)
{
Con.Open();
}
Cmd = new SqlCommand(insert_query, Con);
Cmd.ExecuteNonQuery();
Con.Close();
MessageBox.Show("The new Student " + txtName.Text + "( S-" + cmbMemNo.Text + " ) has successfully inserted into the system!!!", "INSERTED!!!", MessageBoxButtons.OK, MessageBoxIcon.Information);
Clear();
**第二个选项-设置Con.Close();在最后尝试捕获之内{} **
try
{
String insert_query = "INSERT INTO StReg VALUES('" + cmbMemNo.Text + "','" + txtFName.Text + "','" + txtName.Text + "','" + Gender + "','" + dtpDOB.Text + "','" + txtTelNo.Text + "','" + txtSchool.Text + "','" + txtAdNo.Text + "','" + txtMom.Text + "','" + txtMomOcc.Text + "','" + txtDad.Text + "','" + txtDadOcc.Text + "')";
if (Con.State == System.Data.ConnectionState.Closed)
{
Con.Open();
}
Cmd = new SqlCommand(insert_query, Con);
Cmd.ExecuteNonQuery();
//Con.Close(); - move this line to finally
MessageBox.Show("The new Student " + txtName.Text + "( S-" + cmbMemNo.Text + " ) has successfully inserted into the system!!!", "INSERTED!!!", MessageBoxButtons.OK, MessageBoxIcon.Information);
Clear();
}
catch (Exception ex)
{
MessageBox.Show("Error occur :"+ ex.Message);
}
finally {
Con.Close();
}
答案 2 :(得分:0)
无法在obj'dbo.StReg'中插入重复键。重复的键值为()。
对于StReg表,主键是什么?确保将主键设置为NOT NULL并为每个记录插入唯一值。如果您对主键使用UNIQUEIDENTIFIER类型,则可以在“默认值”或“绑定”中添加NEWID(),这将自动为每个新记录分配新的Guid。