2016-04-25 4 views
1

У меня есть таблица с двумя столбцами, Prime_GuestID и Dup_GuestID указать ссылки между GuestID-х и ID (ы) он заменяет (дубликаты записи)Избегайте ключи столкновения заявления Update SQL Merge

Теперь я хочу пройти через ряд других таблиц отношений формата и обновить любые вхождения Dup_GuestID в его Prime_GuestID.

Однако, если Prime_GuestID уже имеет запись для данного ThingID, вместо этого мне нужно удалить эту строку из таблицы отношений.

В настоящее время я использую следующий сценарий, хотя, хотя он работает в большинстве случаев, он терпит неудачу, если два обновления Dup_GuestID для одного и того же Prime_GuestID для заданного ThingID. Кажется, что заявление о слиянии приостанавливает все изменения перед их созданием, поэтому моя проверка на конфликт не обнаружит их.

MERGE Thing_Relation AS t 
USING Guest_Relation AS g 
    ON t.GuestID = g.Dup_GuestID 
WHEN MATCHED AND EXISTS ( -- Clash Check here 
         select * 
         from Thing_Relation AS t2 
         where t2.ThingID = t.ThingID 
         and t2.GuestID = g.Prime_GuestID 
         ) 
THEN DELETE 
WHEN MATCHED 
THEN UPDATE SET t.GuestID = g.Prime_GuestID 

Есть ли лучший способ делать проверку на «Когда согласована и существует» для проверки столкновений, которые могут возникнуть в результате этого слияния? Или есть лучший способ сделать все это?

EDIT: Вот несколько примеров данных для таблицы

Thing_Relation   Guest_Relation 
ThingID | GuestID  Prime_GuestID | Dup_GuestID 
------------------  --------------------------- 
1  | 101      101 | 102 
1  | 102      107 | 104 
2  | 103      107 | 105 
3  | 104 
3  | 105 

Thing_Relation after merge 
ThingID | GuestID  
------------------  
1  | 101    
2  | 103 
3  | 107  

1-| 102 получает изменено на 1 | 101, которая уже существует, так как строка будет удалена. 2 | 103 не влияет 3 | 104 изменен на 3 | 107, а так как 3 | 105 также изменяется на 3 | 107, но предыдущее обновление еще не произошло, но оно не подхвачено предложением EXISTS.

+0

Я не уверен в вашем основном синтаксисе. Как вы сказали, слияние не будет выполнено, если обновление не является детерминированным.so, а не пытается его решить, если вы все еще хотите продолжить и обновить .. вы можете использовать производную таблицу который будет иметь только одно совпадение – TheGameiswar

+0

Извините, я не совсем понимаю ваш комментарий. Если строка будет обновлена ​​до того, что столкнулось бы в таблице, я хочу удалить эту строку. Однако, если столкновение было сгенерировано предыдущим обновлением на шаге слияния, то мое условие 'EXISTS' не найдет его. Есть ли лучшее условие, которое я мог бы использовать, чтобы обойти эту проблему? – skeletalmonkey

+0

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

ответ

0

Вы правы, MERGE не выполнит ваши проверки изменений, внесенных самим оператором MERGE. Это основное свойство MERGE. Немногие из вариантов могут быть следующими:

  1. Создайте TRIGGER в UPDATE, который будет продолжать проверять наличие столкновений при каждом обновлении и удалять повторяющиеся строки. ИЛИ
  2. просто напишите два разных оператора один для UPDATE, позже один DELETE для дубликатов записей.
Смежные вопросы