Как параметр Table Valued передается в оператор Merge, получая ошибку Duplicate Key для пустой таблицы?

Я отправляю табличный параметр в хранимую процедуру MS SQL Server 2008 R2 из кода C#. Я получаю сообщение об ошибке: "Нарушение ограничения PRIMARY KEY" PK_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)
  • ПК является единственным ограничением.

Хранимая процедура:

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 контрольный список: 1 iDsList: (список из 71 уникального целого числа)

Цель моей функции состоит в том, чтобы кто-то нажимал "проверить все" в сетке, и я сохранял проверенный статус в каждой из затронутых строк в базе данных, не просматривая каждую. Это вспомогательная таблица, созданная путем нормализации, поэтому для каждого может быть или не быть запись, следовательно, слияние. Я получил ошибку и решил упростить проблему, обрезав таблицу и повторив попытку, но даже с абсолютно пустой таблицей я получаю ошибку "дубликат ключа".

Таким образом, основной вопрос заключается в том, как у меня может быть ошибка дублированного ключа без записей, и как я могу это исправить, чтобы я больше не получал ошибку?

1 ответ

Решение

В Example Таблица Month а также Year Столбцы также помечены как первичный ключ вместе с ID и я думаю, что они не содержат уникальных значений. Удалите ограничения первичного ключа из Month а также YEAR Столбцы в таблице и попробуйте еще раз.

Другие вопросы по тегам