Хобрук: Ваш путь к мастерству в программировании

SQL Server ignore_dup_key явно игнорируется для оператора слияния

SQL Server 2008.

У меня есть несколько частей кода, работающих вместе, и эффект довольно странный, поэтому я решил поделиться.

У меня есть таблица с электронными письмами - для простоты предположим, что есть 2 столбца: идентификатор идентификатора (1,1) int первичный ключ адрес электронной почты varchar (900)

Также в столбце электронной почты есть уникальный ключ с IGNORE_DUP_KEY = ON.

С другой стороны проблемы есть оператор слияния:

merge into dbo.email
using (
     select distinct email t from #t
) p 
ON t = email
when not matched by target then
insert (email) values  (t);

Стоит отметить, что #t в основном (для целей этого запроса) представляет собой таблицу с одним столбцом и электронной почтой varchar(500).

Что удивительно, так это то, что запрос не удался:

«Нарушение ограничения UNIQUE KEY« uq_email ». Невозможно вставить дубликат ключа в объект dbo.email»

Однако это работает безупречно:

insert into dbo.email (email) select email from #t

Хотя я, очевидно, могу обойти эту проблему (инструкция вставки в любом случае быстрее, так что это путь), я понятия не имею, почему инструкция MERGE не удалась. Любые идеи, кто-нибудь?

РЕДАКТИРОВАТЬ: Полный вариант использования: Шаг 1:

create table #temp (
col1 varchar(500),
col2 varchar(500),
col3 varchar(500),
col4 varchar(500),
col5 varchar(500),
email varchar(500),
id int)

Шаг 2:

#temp заполняется из файла CSV для многих целей.

Шаг 3:

слияние с dbo.email с помощью (выберите отдельный адрес электронной почты t из #temp) p ON t = адрес электронной почты, если он не соответствует цели, затем вставьте (адрес электронной почты) значения (t);

Шаг 0 — СОЗДАЙТЕ скрипт для dbo.email:

CREATE TABLE dbo.email (
id int identity(1,1) not null,
email varchar(900) null,
loaddate date default null,
constraint [PK__email__1111] PRIMARY KEY CLUSTERED
(
    id asc
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON PRIMARY,
CONSTRAINT [uq_email] UNIQUE NONCLUSTERED
(
     EMAIL asc
)
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = ON, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON PRIMARY
) ON PRIMARY

Я не могу сделать намного больше, не предоставив вам сотни гигабайт данных, о чем, очевидно, не может быть и речи.


  • На основе предоставленной вами информации оператор должен работать правильно и не пытаться вставить туда, где уже существуют совпадающие строки. Есть ли триггер в целевой таблице email? 10.02.2012
  • Нет. Там действительно больше ничего нет. Я также удивлен, что это не удалось, поскольку я не вижу причин (очевидно). Возможно, это ошибка в SQL Server. В конце концов, как говорил мой проф, это всего лишь программа :-. 10.02.2012
  • Можете ли вы опубликовать полный пример, демонстрирующий проблему? Я создал тест на основе предоставленной вами информации, и он работает так, как ожидалось. 10.02.2012
  • Побочный момент: если вам нужно игнорировать дубликаты, какова ценность наличия уникального ограничения вообще? 10.02.2012
  • В таблице должны быть уникальные адреса электронной почты, однако есть много источников данных, вставляющих туда данные, и они могут иметь дубликаты - сами по себе и между собой. 10.02.2012
  • В этом случае я не понимаю, зачем переключать IGNORE_DUP_KEY = ON — это означает, что для операторов INSERT разрешено вставлять дубликаты ключей (что в противном случае нарушило бы ограничение) — см. msdn.microsoft.com/en-us/library/ms186869.aspx 10.02.2012

Ответы:


1

Ваш столбец электронной почты допускает null значений. Если у вас есть значение null в цели и значение null в источнике, они не будут совпадать в выражении on. У вас будет уникальное исключение ограничения при вставке второго значения null.

Попробуйте это вместо этого:

merge into dbo.email
using (
     select distinct email t from #t where email is not null
) p 
ON t = email
when not matched by target then
insert (email) values  (t);

Обновление:
Что касается ignore_dup_key, вы должны прочитать раздел примечаний в документации по слияние:

Если для IGNORE_DUP_KEY установлено значение ON для любых уникальных индексов в целевой таблице, MERGE игнорирует этот параметр.

Чтобы иметь уникальное ограничение в SQL Server, которое допускает несколько нулевых значений, вы должны вместо этого добавить уникальный отфильтрованный индекс.

create unique index UX_xx on TableName(ColName) where ColName is not null
10.02.2012
  • Блестящий улов. Также я, вероятно, никогда не привыкну к тому, что в SQL Server, в отличие от ORacle, уникальный столбец допускает только одно нулевое значение. -> Тем не менее, хотя это и объясняет, почему слияние не поймало ситуацию null = null, это не объясняет, почему ignore_dup_key не будет работать в этом случае. В конце концов, он работает для оператора вставки. 10.02.2012
  • Новые материалы

    React on Rails
    Основное приложение Reverb - это всеми любимый монолит Rails. Он отлично обслуживает наш API и уровень просмотра трафика. По мере роста мы добавляли больше интерактивных элементов..

    Что такое гибкие методологии разработки программного обеспечения
    Что представляют собой гибкие методологии разработки программного обеспечения в 2023 году Agile-методологии разработки программного обеспечения заключаются в следующем: И. Введение A...

    Ториго  — революция в игре Го
    Наш следующий вызов против ИИ и для ИИ. Сможет ли он победить людей в обновленной игре Го? Обратите внимание, что в следующей статье AI означает искусственный интеллект, а Goban  —..

    Простое развертывание моделей с помощью Mlflow — Упаковка классификатора обзоров продуктов NLP от HuggingFace
    Как сохранить свои модели машинного обучения в формате с открытым исходным кодом с помощью MLFlow, чтобы позже получить возможность легкого развертывания. Сегодня модели упаковки имеют несколько..

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

    Раскрытие возможностей НЛП: часть речевой маркировки и ее проблемы
    В сфере обработки естественного языка (NLP) маркировка частей речи (POS) выступает в качестве фундаментального метода, позволяющего компьютерам понимать и анализировать человеческий язык на..

    Под поверхностью: раскрытие деталей системы с помощью инструментов Linux CLI
    Чем больше вы изучаете Linux и продвигаетесь вперед, тем больше вам нужно проверять информацию о вашей системе. Эта информация может касаться аппаратного обеспечения, такого как процессор,..