How is a Table Valued Parameter passed into Merge statement getting Duplicate Key error on an empty table?

StackOverflow https://stackoverflow.com/questions/8524537

سؤال

I am sending a Table Valued Parameter into an MS SQL Server 2008 R2 stored procedure from C# code. The error I receive is: "Violation of PRIMARY KEY constraint 'PK_Example.ExampleTable'. Cannot insert duplicate key in object 'Example.ExampleTable'. The statement has been terminated."

Table structure: 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 is the only constraint.

Stored Procedure:

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

As for the IDLIST part above: CREATE TYPE IDLIST AS TABLE (n int);

C# Code:

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();

On execution, I get the error. In an example set, the variables are as follows: year: 2011 month: 11 checkstatus: 1 iDsList: (List of 71 unique integers)

The intent of my function is that someone clicks "check all" on a grid and I save the checked status to each of the affected rows in the database without going through each one. This is an ancillary table created by normalization, so there may or may not be a record for each, hence the merge. I got the error and decided to simplify the problem by truncating the table and trying again, but even with an absolutely empty table I get the "duplicate key" error.

So the core question is how I can have a duplicate key error with no records, and how do I fix it so I don't get the error anymore?

هل كانت مفيدة؟

المحلول

In Example Table Month and Year Columns are also marked as Primary Key along with ID and i guess they do not contain Unique Values. Remove the Primary Key Constraints from Month and YEAR Columns in the table and try again.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top