Я вставляю в базу данных SQL из нескольких процессов. Вероятно, что процессы иногда пытаются вставить дубликаты данных в таблицу. Я попытался написать запрос таким образом, чтобы обрабатывать дубликаты, но я все равно получаю:
System.Data.SqlClient.SqlException: Violation of UNIQUE KEY constraint 'UK1_MyTable'. Cannot insert duplicate key in object 'dbo.MyTable'.
The statement has been terminated.
Мой запрос выглядит примерно так:
INSERT INTO MyTable (FieldA, FieldB, FieldC)
SELECT FieldA='AValue', FieldB='BValue', FieldC='CValue'
WHERE (SELECT COUNT(*) FROM MyTable WHERE FieldA='AValue' AND FieldB='BValue' AND FieldC='CValue' ) = 0
Ограничение "UK1_MyConstraint" говорит, что в MyTable комбинация из трех полей должна быть уникальной.
Мои вопросы:
- Почему это не работает?
- Какую модификацию мне нужно сделать, чтобы исключить исключение из-за нарушения ограничения?
Обратите внимание, что я знаю, что существуют другие подходы к решению исходной проблемы "INSERT if not exists", например (в резюме):
- Использование TRY CATCH
- ЕСЛИ НЕ СУЩЕСТВУЕТ ВСТАВИТЬ (внутри транзакции с сериализуемой изоляцией)
Должен ли я использовать один из подходов?
Изменить 1 SQL для создания таблицы:
CREATE TABLE [dbo].[MyTable](
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[FieldA] [bigint] NOT NULL,
[FieldB] [int] NOT NULL,
[FieldC] [char](3) NULL,
[FieldD] [float] NULL,
CONSTRAINT [PK_MyTable] PRIMARY KEY NONCLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON),
CONSTRAINT [UK1_MyTable] UNIQUE NONCLUSTERED
(
[FieldA] ASC,
[FieldB] ASC,
[FieldC] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
)
Изменить 2 Решение:
Просто обновить это - я решил использовать реализацию JFDI, предложенную в связанном вопросе (ссылка). Хотя мне все еще интересно, почему исходная реализация не работает.