我正在做一个项目来为图书馆开发图书馆管理系统。在其中,我通过将他们的详细信息保存到数据库来注册学生。首先插入记录时,保存时没有给定的成员编号。
然后,当我开始保存下一个学生的详细信息时,我收到一条错误消息“违反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)
);
无论我怎么努力找到任何错误,我仍然无法弄明白。请帮忙!
由于您未关闭连接,因此未关闭连接。在关闭连接并且您已打开连接之前发生异常。像这样做所有的查询:
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);
我建议你将主键设置为自动增量。在自动生成时不需要插入主键值
创建你的表是这样的
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();不执行,连接不会关闭。你有两个选择,
第一个选项 - 检查连接状态,如果关闭则打开
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 catch catch {} **
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();
}
无法在obj'dbo.StReg'中插入重复键。重复键值为()。
对于StReg表,主键是什么?确保将主键设置为NOT NULL并为每条记录插入唯一值。如果您使用UNIQUEIDENTIFIER类型作为主键,则可以在默认值或Binding中添加NEWID(),这将自动为每个新记录分配新的Guid。