2010-08-03 4 views
1

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

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

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

ответ

1

Если я правильно понимаю, вы хотите делать ОБНОВЛЕНИЯ без указания необходимой логики 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. использовать ВМЕСТО UPDATE триггера на «перехват» обновление и только сделать ОБНОВЛЕНИЕ который не будет создавать дубликат.
  3. Используйте технику обработки строк за строкой, такую ​​как курсоры, и оберните каждый UPDATE в TRY ... CATCH ... или независимо от эквивалента языка

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

+0

Я надеялся, что будет какой-то механизм, похожий на IGNORE_DUP_KEY, но для обновлений. Увы, мне придется использовать свой первый вариант выше. Большое спасибо. – DEH

0

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

Edit: Я думаю, что эта ссылка поможет в том, что:

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

+1

MERGE только MSSQL 2008, и DEH использует MSSQL 2005 – Pondlife

+0

Слишком плохо, но вы правы. – hol

0

Я не уверен, что на самом деле происходит, но если вы вставляете дубликаты и обновление первичных ключей в рамках основной массы процесс загрузки, тогда для вас может быть промежуточной таблицей. Вы создаете таблицу, которая, по вашему мнению, пуста до массовой загрузки, затем загружает ее с 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 
         ) 

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