SQL Server Как вставить несколько значений, исключая повторяющиеся значения

#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 , чтобы проверить, что значения не существуют, или используйте a MERGE ?

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