Ограничение SQL IGNORE_DUP_KEY при обновлении - PullRequest
1 голос
/ 03 августа 2010

У меня есть ограничение на таблицу с IGNORE_DUP_KEY. Это позволяет частичным вставкам работать частично, когда некоторые записи являются дуплексами, а некоторые нет (только вставка без дуплексов). Однако он не позволяет обновлениям работать частично, и я хочу, чтобы обновлялись только те записи, в которых не будут создаваться дубликаты.

Кто-нибудь знает, как я могу поддержать IGNORE_DUP_KEY при применении обновлений?

Я использую MS SQL 2005

Ответы [ 3 ]

1 голос
/ 03 августа 2010

Если я правильно понимаю, вы хотите выполнить ОБНОВЛЕНИЯ без указания необходимой логики WHERE, чтобы избежать создания дубликатов?

create table #t (col1 int not null, col2 int not null, primary key (col1, col2))

insert into #t 
select 1, 1 union all 
select 1, 2 union all 
select 2, 3

-- you want to do just this...
update #t set col2 = 1

-- ... but you really need to do this
update #t set col2 = 1
where not exists (
    select * from #t t2
    where #t.col1 = t2.col1 and col2 = 1
    )

Основные варианты, которые приходят на ум:

  1. Используйте полный оператор UPDATE, чтобы избежать создания дубликатов
  2. Используйте триггер INSTEAD OF UPDATE, чтобы «перехватить» UPDATE, и выполняйте только те ОБНОВЛЕНИЯ, которые не создадут дубликат
  3. Используйте строковую технику обработки, такую ​​как курсоры, и переносите каждое ОБНОВЛЕНИЕ в TRY ... CATCH ... или любой другой эквивалент языка

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

0 голосов
/ 03 августа 2010

Я не уверен, что на самом деле происходит, но если вы вставляете дубликаты и обновляете первичные ключи как часть процесса массовой загрузки, тогда промежуточная таблица может быть решением для вас.Вы создаете таблицу, которую убедитесь, что она пуста до массовой загрузки, затем загружаете ее со 100% необработанными данными из файла, а затем обрабатываете эти данные в ваших реальных таблицах (лучше всего использовать набор на основе).Вы можете сделать что-то вроде этого, чтобы вставить все строки, которые еще не существуют:

INSERT INTO RealTable
        (pk, col1, col2, col3)
    SELECT
        pk, col1, col2, col3
        FROM StageTable s
        WHERE NOT EXISTS (SELECT
                              1
                              FROM RealTable r
                              WHERE s.pk=r.pk
                         )

Лучше всего избегать дублирования.Вы также можете выполнить ОБНОВЛЕНИЯ для своей реальной таблицы, присоединившись к промежуточной таблице и т. Д. Это позволит избежать необходимости «обойти» ограничения.Когда вы работаете над ограничениями, вы обычно создаете трудные для поиска ошибки.

0 голосов
/ 03 августа 2010

У меня такое чувство, что вы должны использовать инструкцию MERGE, а затем в части обновления вы не должны обновлять ключ, который хотите иметь уникальным.Это также означает, что вы должны определить в своей таблице, что ключ является уникальным (установка уникального индекса или определение в качестве первичного ключа).Тогда любое обновление или вставка с дублирующим ключом завершится неудачей.

Редактировать: я думаю, что эта ссылка поможет на этом:

http://msdn.microsoft.com/en-us/library/bb522522.aspx

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