C# 违反主键约束。无法在对象-ADO.NET中插入重复键
我正在尝试插入一个新的人的数据,我可以在第一次尝试时插入,但当第二次尝试时出现主键错误冲突,事实上,每次尝试添加一个新的人时,人id(personId)都会增加,因此我意识到错误是主键 餐桌上的人C# 违反主键约束。无法在对象-ADO.NET中插入重复键,c#,sql-server,C#,Sql Server,我正在尝试插入一个新的人的数据,我可以在第一次尝试时插入,但当第二次尝试时出现主键错误冲突,事实上,每次尝试添加一个新的人时,人id(personId)都会增加,因此我意识到错误是主键 餐桌上的人 CREATE TABLE [dbo].[Person] ( [personID] INT NOT NULL, [personName] VARCHAR (50) NOT NULL, PRIMARY KEY CLUSTERED ([personID] ASC) ); 方法
CREATE TABLE [dbo].[Person] (
[personID] INT NOT NULL,
[personName] VARCHAR (50) NOT NULL,
PRIMARY KEY CLUSTERED ([personID] ASC)
);
方法创建和插入新人员
protected void BtnCreate(object sender, EventArgs e)
{
SqlConnection connection = new SqlConnection(connectionString);
//id to new person
int id = 0;
//command
string command = "INSERT INTO [Person] ([personID], [personName]) VALUES (@id, @name)";
SqlCommand cmd = new SqlCommand(command, connection);
cmd.Parameters.AddWithValue("@id", id++);//id increase
cmd.Parameters.AddWithValue("@name", name.Text);
connection.Open();
cmd.ExecuteNonQuery();
connection.Close();
}
CREATE TABLE [dbo].[Person] (
[personID] INT NOT NULL,
[personName] VARCHAR (50) NOT NULL,
PRIMARY KEY CLUSTERED ([personID] ASC)
);
有什么建议吗?您当前的代码无法再次运行,因为您增加的
id
变量是在堆栈上分配的局部变量。当方法退出时,堆栈上的所有内容都将被清除。再次单击按钮可重新输入该方法,但变量将重置为零,增量将再次将变量设置为1。因此personID字段的重复异常
我建议在添加属性时更改您的personID
列。通过这种方式,数据库自行计算下一个要分配给
personID
字段的值,您不需要记住最后分配给表的id是什么(在多用户环境中,这几乎不可能以安全的方式实现)
添加IDENTITY属性后,可以读回数据库分配给personID
字段的值,将查询更改为
string command = @"INSERT INTO [Person] ([personName])
OUTPUT INSERTED.personID
VALUES (@name)";
并使用ExecuteScalar运行查询
int id = Convert.ToInt32(cmd.ExecuteScalar());
当前代码无法再次工作,因为您递增的
id
变量是在堆栈上分配的局部变量。当方法退出时,堆栈上的所有内容都将被清除。再次单击按钮可重新输入该方法,但变量将重置为零,增量将再次将变量设置为1。因此personID字段的重复异常
我建议在添加属性时更改您的personID
列。通过这种方式,数据库自行计算下一个要分配给
personID
字段的值,您不需要记住最后分配给表的id是什么(在多用户环境中,这几乎不可能以安全的方式实现)
添加IDENTITY属性后,可以读回数据库分配给personID
字段的值,将查询更改为
string command = @"INSERT INTO [Person] ([personName])
OUTPUT INSERTED.personID
VALUES (@name)";
并使用ExecuteScalar运行查询
int id = Convert.ToInt32(cmd.ExecuteScalar());
Steve有一个很好的答案,或者,如果您不能重新安排DB模式,那么您可以这样做:
protected void BtnCreate(object sender, EventArgs e)
{
SqlConnection connection = new SqlConnection(connectionString);
connection.Open();
SqlCommand idcommand = new SqlCommand("select max([personID]) from Person", connection)
//id to new person
int id = ((int)idcommand.ExecuteScalar()) + 1;
//command
string command = "INSERT INTO [Person] ([personID], [personName]) VALUES (@id, @name)";
SqlCommand cmd = new SqlCommand(command, connection);
cmd.Parameters.AddWithValue("@id", id++);//id increase
cmd.Parameters.AddWithValue("@name", name.Text);
cmd.ExecuteNonQuery();
connection.Close();
}
Steve有一个很好的答案,或者,如果您不能重新安排DB模式,那么您可以这样做:
protected void BtnCreate(object sender, EventArgs e)
{
SqlConnection connection = new SqlConnection(connectionString);
connection.Open();
SqlCommand idcommand = new SqlCommand("select max([personID]) from Person", connection)
//id to new person
int id = ((int)idcommand.ExecuteScalar()) + 1;
//command
string command = "INSERT INTO [Person] ([personID], [personName]) VALUES (@id, @name)";
SqlCommand cmd = new SqlCommand(command, connection);
cmd.Parameters.AddWithValue("@id", id++);//id increase
cmd.Parameters.AddWithValue("@name", name.Text);
cmd.ExecuteNonQuery();
connection.Close();
}
如果您不关心
personID
字段的实际值(您的代码似乎表明了这一点)。并且,只希望它是唯一的,并且增加1
在@Steve所指出的示例中,您可以这样定义您的表:(在T-SQL中)
这样就不需要插入personID了
protected void BtnCreate(object sender, EventArgs e)
{
SqlConnection connection = new SqlConnection(connectionString);
//command
string command = "INSERT INTO [Person] ([personName]) VALUES (@name)";
SqlCommand cmd = new SqlCommand(command, connection);
cmd.Parameters.AddWithValue("@name", name.Text);
connection.Open();
cmd.ExecuteNonQuery();
connection.Close();
}
如果您不关心
personID
字段的实际值(您的代码似乎表明了这一点)。并且,只希望它是唯一的,并且增加1
在@Steve所指出的示例中,您可以这样定义您的表:(在T-SQL中)
这样就不需要插入personID了
protected void BtnCreate(object sender, EventArgs e)
{
SqlConnection connection = new SqlConnection(connectionString);
//command
string command = "INSERT INTO [Person] ([personName]) VALUES (@name)";
SqlCommand cmd = new SqlCommand(command, connection);
cmd.Parameters.AddWithValue("@name", name.Text);
connection.Open();
cmd.ExecuteNonQuery();
connection.Close();
}
谢谢大家,你们的答案都是正确的,但我为我的案例找到了更好的解决方案,我使用id作为静态值,至少初始化了一个,并使其失效,它工作正常,符合我的要求,我感谢你们的时间和可用性 我的表不需要使用identity,因为我打算在每次单击按钮创建新人时输入ID增量
protected void BtnCreate(object sender, EventArgs e)
{
SqlConnection connection = new SqlConnection(connectionString);
//id to new person
int id = 0;
//command
string command = "INSERT INTO [Person] ([personID], [personName]) VALUES (@id, @name)";
SqlCommand cmd = new SqlCommand(command, connection);
cmd.Parameters.AddWithValue("@id", id++);//id increase
cmd.Parameters.AddWithValue("@name", name.Text);
connection.Open();
cmd.ExecuteNonQuery();
connection.Close();
}
CREATE TABLE [dbo].[Person] (
[personID] INT NOT NULL,
[personName] VARCHAR (50) NOT NULL,
PRIMARY KEY CLUSTERED ([personID] ASC)
);
我使用了static int id=-1
,功能失效,工作正常
//id to new person
private static int id = -1;
protected void BtnCreate(object sender, EventArgs e)
{
SqlConnection connection = new SqlConnection(connectionString);
//command
string command = "INSERT INTO [Person] ([personID], [personName]) VALUES (@id, @name)";
SqlCommand cmd = new SqlCommand(command, connection);
cmd.Parameters.AddWithValue("@id", id++);//id increase
cmd.Parameters.AddWithValue("@name", name.Text);
connection.Open();
cmd.ExecuteNonQuery();
connection.Close();
}
谢谢大家,你们的答案都是正确的,但我为我的案例找到了更好的解决方案,我使用id作为静态值,至少初始化了一个,并使其失效,它工作正常,符合我的要求,我感谢你们的时间和可用性 我的表不需要使用identity,因为我打算在每次单击按钮创建新人时输入ID增量
protected void BtnCreate(object sender, EventArgs e)
{
SqlConnection connection = new SqlConnection(connectionString);
//id to new person
int id = 0;
//command
string command = "INSERT INTO [Person] ([personID], [personName]) VALUES (@id, @name)";
SqlCommand cmd = new SqlCommand(command, connection);
cmd.Parameters.AddWithValue("@id", id++);//id increase
cmd.Parameters.AddWithValue("@name", name.Text);
connection.Open();
cmd.ExecuteNonQuery();
connection.Close();
}
CREATE TABLE [dbo].[Person] (
[personID] INT NOT NULL,
[personName] VARCHAR (50) NOT NULL,
PRIMARY KEY CLUSTERED ([personID] ASC)
);
我使用了static int id=-1
,功能失效,工作正常
//id to new person
private static int id = -1;
protected void BtnCreate(object sender, EventArgs e)
{
SqlConnection connection = new SqlConnection(connectionString);
//command
string command = "INSERT INTO [Person] ([personID], [personName]) VALUES (@id, @name)";
SqlCommand cmd = new SqlCommand(command, connection);
cmd.Parameters.AddWithValue("@id", id++);//id increase
cmd.Parameters.AddWithValue("@name", name.Text);
connection.Open();
cmd.ExecuteNonQuery();
connection.Close();
}
转到数据库架构并更改personID列,添加IDENTITY属性。然后删除将personIDGo的值设置为数据库架构的任何尝试,并更改personID列以添加IDENTITY属性。然后删除为自己设置personIDI值的任何尝试。我不建议这样做。MAX的问题是当有多个用户插入记录时。迟早会出现错误,因为MAX可能会向多个用户返回相同的值。另一个(次要)问题是这样做会影响性能。我也不建议这样做,这是作为一个替代方案发布的-在一些遗留案例中,您无法更改DB架构。我不建议这样做。MAX的问题是当有多个用户插入记录时。迟早会出现错误,因为MAX可能会向多个用户返回相同的值。另一个(次要)问题是这样做会影响性能。我也不推荐这样做,这是作为一个替代方案发布的-在一些遗留案例中,您无法更改DB架构。