Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 违反主键约束。无法在对象-ADO.NET中插入重复键_C#_Sql Server - Fatal编程技术网

C# 违反主键约束。无法在对象-ADO.NET中插入重复键

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) ); 方法

我正在尝试插入一个新的人的数据,我可以在第一次尝试时插入,但当第二次尝试时出现主键错误冲突,事实上,每次尝试添加一个新的人时,人id(personId)都会增加,因此我意识到错误是主键

餐桌上的人

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架构。