0

我从 C# 代码将表值参数发送到 MS SQL Server 2008 R2 存储过程。我收到的错误是:“违反主键约束'PK_Example.ExampleTable'。无法在对象'Example.ExampleTable'中插入重复键。语句已终止。”

表结构:Example.ExampleTable

[ID] (PK, int, not null)
[Month] (PK, int, not null)
[Year] (PK, int, not null)
[ExternalTextReference] (varchar(150), null)
[UserNote] (varchar(MAX), null)
[CheckedComplete] (bit, not null)
  • PK 是唯一的约束。

存储过程:

ALTER PROCEDURE [dbo].[ExampleSaveGridCheckBatch]
@IDs IDLIST readonly,
@year int = 0,
@month int = 0,
@checked bit = 0
AS
BEGIN
     SET NOCOUNT ON;
     MERGE INTO [Example].[ExampleTable] AS Target 
     USING ( select * from @IDs )
            AS Source (ID)
     ON Target.ID = Source.ID
     WHEN MATCHED THEN
          UPDATE SET CheckedComplete = @checked
     WHEN NOT MATCHED BY TARGET THEN
          INSERT ([ID], [Year], [Month], [CheckedComplete]) 
          VALUES (Source.ID, @year, @month, @checked);
END

至于上面的 IDLIST 部分:CREATE TYPE IDLIST AS TABLE (n int);

C#代码:

DataTable table = new DataTable("IDsList");            
DataColumn col1 = new DataColumn("ID", System.Type.GetType("System.Int32"));
table.Columns.Add(col1);

var cn = new SqlConnection();
createConnection(cn);

SqlCommand cmd = new SqlCommand("ExampleSaveGridCheckBatch", cn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@year", year);
cmd.Parameters.AddWithValue("@month", month);
cmd.Parameters.AddWithValue("@checked", checkstatus);
SqlParameter sparam = new SqlParameter("@IDs", SqlDbType.Structured);
foreach (int item in iDsList)
{
    table.Rows.Add(item);
}
sparam.Value = table;
cmd.Parameters.Add(sparam);

cmd.ExecuteNonQuery();

在执行时,我得到了错误。在示例集中,变量如下:年:2011 月:11 checkstatus:1 iDsList:(71 个唯一整数的列表)

我的功能的目的是有人单击网格上的“全部检查”,然后我将检查的状态保存到数据库中每个受影响的行,而无需遍历每一行。这是通过规范化创建的辅助表,因此每个表可能有也可能没有记录,因此合并。我收到错误并决定通过截断表并重试来简化问题,但即使表完全为空,我也会收到“重复键”错误。

所以核心问题是我如何才能在没有记录的情况下出现重复键错误,以及如何修复它以便不再收到错误?

4

1 回答 1

1

ExampleMonthYear列中也被标记为主键ID,我猜它们不包含唯一值。从表中的列中删除主键约束,Month然后重试。YEAR

于 2011-12-17T06:19:05.833 回答