Обнаружение изменений между записями в двух таблицах

У меня есть 3 таблицы:

  1. Постановка: ежемесячно вставляются записи о сотрудниках.
  2. Мастер: таблица содержит все ранее введенные записи из промежуточных, уникальные записи.
  3. Изменения: отслеживает все изменения — не имеет первичного ключа.

Таблицы имеют 10 столбцов. В промежуточной таблице каждый месяц у нас около 2 500 000 записей. Используя курсор, я могу вставлять новые записи из промежуточной таблицы в основную таблицу.

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

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

WHERE Staging.FirstName <> Master.FirstName
   OR Staging.LastName <> Master.LastName
   OR ...

И так по 10 колонок или есть способ проще?


person user2726975    schedule 16.10.2013    source источник
comment
Я попытался немного переформулировать ваш вопрос, пожалуйста, посмотрите, все ли это то, что вы имели в виду.   -  person CodeCaster    schedule 16.10.2013
comment
@CodeCaster Да .. это то, что я хочу   -  person user2726975    schedule 16.10.2013


Ответы (2)


Если две таблицы действительно идентичны, вы можете создать сохраняемый вычисляемый столбец в каждой таблице, представляющий контрольную сумму всей строки (см. http://technet.microsoft.com/en-us/library/ms189788.aspx), создайте для него индекс, а затем используйте его для своих объединений.

person Ken Smith    schedule 16.10.2013
comment
Ну, есть дополнительный столбец для проверки состояния записи (обработана или нет) в промежуточной таблице. - person user2726975; 16.10.2013
comment
Вероятно, вы могли бы просто вычислить контрольную сумму для определенных столбцов, например, alter table Staging add cs CHECKSUM(FirstName, LastName, ...) - person Ken Smith; 16.10.2013
comment
Я читал об этом, и многие говорят, что будут коллизии и, следовательно, не лучший способ обнаружения изменений. - person user2726975; 17.10.2013
comment
Хороший момент, и в этом случае вы можете использовать UDF на основе CLR, чтобы сделать что-то подобное. Старый добрый хэш MD5, вероятно, даст вам все необходимое хеширование без коллизий. - person Ken Smith; 17.10.2013

Использование курсора для миллионов строк звучит не очень весело.

Возможно, вам стоит взглянуть на EXCEPT/MERGE

WITH NewAndChanged AS (
    SELECT Stage.Id
          ,Stage.Col1
          ,Stage.Col2
    FROM Stage
  EXCEPT
    SELECT Master.Id
          ,Master.Col1
          ,Master.Col2
    FROM Master
)
MERGE Master
USING NewAndChanged
      ON Master.Id = NewAndChanged.Id
WHEN MATCHED
     THEN UPDATE SET
         Col1 = NewAndChanged.Col1
        ,Col2 = NewAndChanged.Col2
WHEN NOT MATCHED
     THEN INSERT (
              Id
             ,Col1
             ,Col2
          )
          VALUES (
              NewAndChanged.Id
             ,NewAndChanged.Col1
             ,NewAndChanged.Col2
          )
person adrianm    schedule 16.10.2013
comment
Спасибо за все ваши ответы .. Я не могу проголосовать, потому что моя репутация ‹ 15. Я принял ответ Адрианма. - person user2726975; 17.10.2013