#sql #sql-server
#sql #sql-сервер
Вопрос:
Я пытаюсь вставить строки из другой таблицы базы данных в новую таблицу базы данных, получая приведенную ниже ошибку, если в запросе нет условия where.
Нарушение ограничения УНИКАЛЬНОГО КЛЮЧА ‘NK_LkupxViolations’. Не удается вставить дубликат ключа в объект ‘dbo.LkupxViolation’. Значение повторяющегося ключа равно (00000000-0000-0000-0000-000000000000, (не указано)).
Затем я написал приведенный ниже запрос, добавив, какие условия он выполнял, но он не вставлял ожидаемое количество строк.
IF EXISTS(SELECT 1 FROM sys.tables WHERE name = 'LkupxViolation')
BEGIN
INSERT INTO dbo.[LkupxViolation] SELECT * FROM [DMO_DB].[dbo].[LkupxViolation] where CGRootId not in (select CGRootId from dbo.[LkupxViolation])
and Name not in (select name from dbo.[LkupxViolation])
END
ELSE
PRINT 'LkupxViolation table does not exist'
Уникальный ключ в таблице создается как:
CONSTRAINT [NK_LkupxViolations] UNIQUE CLUSTERED
(
[CGRootId] ASC,
[Name] ASC
)
Комментарии:
1. Какую базу данных вы используете? Опубликованный вами код не похож на Oracle (хотя вы отметили вопрос как «Oracle11g»).
2. @Littlefoot SQL server
3. Очевидно, что другая БД не имеет уникального ключа для cgrootid / name, если он имеет несколько одинаковых значений. Либо отфильтруйте их с помощью предложения Where, создайте неуникальный индекс или удалите ключ. Мы не можем сказать вам, что делать, потому что мы ничего не знаем о ваших бизнес-потребностях в этих данных
4. Проверьте
@@ROWCOUNT
в следующей строке, смотрите Здесь рекомендации для UPSERTs
Ответ №1:
Попробуйте использовать NOT EXISTS
:
INSERT INTO dbo.[LkupxViolation]
SELECT *
FROM [DMO_DB].[dbo].[LkupxViolation] remove_l
WHERE NOT EXISTS (SELECT 1
FROM dbo.[LkupxViolation] local_l
WHERE local_l.Name = remote_l.Name AND
local_l.CGRootId = remote_l.CGRootId
);
При этом проверяется наличие обоих значений в одной строке. Кроме того, NOT IN
это небезопасно NULL
. Если какие-либо значения, сгенерированные подзапросом, являются NULL
, то все строки отфильтровываются.