#sql #sql-server #sql-insert
#sql #sql-сервер #sql-вставка
Вопрос:
Я разрабатываю запрос для программы, в которой пользователь должен ввести одно или несколько значений в таблицу БД.
Проблема с запросом заключается в том, что при попытке вставить кратные значения может быть, что некоторые из этих значений повторяются в таблицах, и предупреждение будет отображать только одно повторяющееся значение за раз, и это может быть проблемой при работе с более чем 1000 значениями.
Сообщение об ошибке:
Не удается вставить повторяющуюся ключевую строку в объект ‘ItemWebCategory’ с уникальным индексом ‘IX_StyleID_WebCategoryID’. Повторяющееся значение ключа равно (1109068, 99999).
Запрос
insert into ItemWebCategory (Style_id,WebCategoryID)
select distinct Style_id,WebCategoryID = '99999'
from ItemCategory
where style_id in ('1109068','168175', '68435', '545457', '69189')
Вопрос
Как я могу изменить запрос, чтобы он мог пропускать / исключать все повторяющиеся значения и вставлять только те значения, которые не существуют в таблице?
Комментарии:
1. Используйте a
WHERE
, чтобы проверить, что значения не существуют, или используйте aMERGE
?2.
WebCategoryID = '99999'
это логическое поле?
Ответ №1:
Попробуйте что-то вроде этого:
INSERT INTO ItemWebCategory ( Style_id, WebCategoryID )
SELECT DISTINCT
Style_id,
'99999' AS WebCategoryID
FROM ItemCategory WHERE Style_id NOT IN (
SELECT Style_id FROM ItemWebCategory
);
NOT IN
Исключает любые Style_id
значения, которые уже существуют в ItemWebCategory
.
Комментарии:
1.
NOT IN
следует избегать, поскольку это приводит к неправильным результатам для столбцов с нулевым значением. ИспользуйтеNOT EXISTS
илиEXCEPT
вместо
Ответ №2:
У вас есть два простых варианта:
NOT EXISTS
insert into ItemWebCategory (Style_id,WebCategoryID)
select distinct Style_id,WebCategoryID = '99999'
from ItemCategory ic
where style_id in ('1109068','168175', '68435', '545457', '69189')
AND NOT EXISTS (SELECT 1
FROM ItemWebCategory iwc
WHERE ic.Style_id = iwc.Style_id
);
EXCEPT
insert into ItemWebCategory (Style_id,WebCategoryID)
select Style_id,WebCategoryID = '99999'
from ItemCategory
where style_id in ('1109068','168175', '68435', '545457', '69189')
EXCEPT
SELECT Style_id
FROM ItemWebCategory;
Теперь нет необходимости в DISTINCT
том, что EXCEPT
подразумевает DISTINCT
- Еще одним полезным вариантом является a
MERGE
. Это имеет преимущества в производительности из-за защиты от Хэллоуина (целая тема сама по себе), как объяснил Пол Уайт:
MERGE ItemWebCategory AS target
USING (
select Style_id, WebCategoryID = '99999'
from ItemCategory
where style_id in ('1109068','168175', '68435', '545457', '69189')
) AS source
ON target.Style_id = source.Style_id
WHEN NOT MATCHED THEN INSERT
(Style_id, WebCategoryID)
VALUES (source.Style_id, source.WebCategoryID);