如何将表值参数传递到合并语句中,在空表上获得重复键错误?
本文关键字:错误 参数传递 语句 合并 | 更新日期: 2023-09-27 18:17:54
我从c#代码发送一个表值参数到MS SQL Server 2008 R2存储过程。我收到的错误是:"违反了主键约束'PK_Example.ExampleTable'。不能在对象'Example.ExampleTable'中插入重复键。语句已被终止。"
表结构:的例子。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);
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();
在执行时,我得到错误。在示例集中,变量如下:年:201111月:checkstatus: 1iDsList: (List of 71 unique integers)
我的函数的意图是,有人单击网格上的"check all",我将检查状态保存到数据库中每个受影响的行,而不需要逐个检查。这是一个通过规范化创建的辅助表,因此每个表可能有也可能没有记录,因此需要合并。我得到了错误,并决定通过截断表并再次尝试来简化问题,但即使有一个绝对空的表,我也会得到"重复键"错误。
所以核心问题是我如何可以有一个重复的键错误没有记录,我如何修复它,所以我不会得到错误了吗?
在Example
表Month
和Year
列也标记为主键与ID
,我猜他们不包含唯一值。删除表中Month
和YEAR
列的主键约束,然后重试