SSIS как найти удаленные записи

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

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

(К вашему сведению ~~ Я не проверял, существует ли запись в таблице назначения, и если да, обновите еще вставку, но не знаю, как найти удаленные данные)


person Echo    schedule 24.07.2012    source источник


Ответы (4)


Другой возможный подход:

Предполагая, что вы получаете все записи из источника, а не только импорт и обновления:

  1. Изменить пакет, чтобы пометить записи, которые были вставлены или обновлены, с использованием уникального идентификатора или даты и времени запуска.

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

Опять же, при условии, что отправляются все записи, а не только импорт и обновления. Но опять же, если вы не получите все записи, будет физически невозможно определить, была ли запись удалена.

person Aphillippe    schedule 25.07.2012

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

В результате, лучший способ справиться с этим, вероятно, находится на стороне источника. Два распространенные подходы представляют собой "обратимое удаление", где вы устанавливаете столбец флага, чтобы пометить строку как удаленную; или триггер, который записывает PK удаленной строки в таблицу журнала (или перемещает всю строку в таблицу архивного журнала). Затем ваш процесс ETL просматривает флаги или таблицу журнала/архива, чтобы определить, какие строки были удалены с момента последней загрузки.

Другая возможность заключается в том, что исходная платформа предлагает некоторую встроенную функцию, которую вы можете использовать для отслеживания удаленных строк, например. CDC в SQL Server. Но если у вас нет никакого контроля над исходной базой данных (если это вообще база данных), тогда может не быть альтернативы сравнению полного набора данных.

person Pondlife    schedule 24.07.2012
comment
Большое спасибо за этот ответ! К сожалению, я полностью не контролирую исходную базу данных, поэтому мне приходится сравнивать полный набор данных. Но как я мог их сравнить, если источником является поток данных, а не таблица, и поэтому его нельзя использовать в качестве таблицы поиска? - person Echo; 24.07.2012
comment
Вы можете использовать преобразование поиска, особенно если объем данных велик. , может быть проще и быстрее записать значения PK из потока данных в физическую таблицу и использовать запрос SQL для идентификации удаленных строк. - person Pondlife; 25.07.2012

Один из возможных подходов:

  1. Перед запуском пакета удалите записи таблицы назначения (используя хранимую процедуру)
  2. Просто импортируйте все записи в целевую таблицу

Плюсы:

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

Минусы:

У вас не будет никакой исторической информации (если это требуется)

person Aphillippe    schedule 25.07.2012
comment
И еще один недостаток: просто импортировать все записи не очень хорошо работает для большого количества строк. Хотя, поскольку ОП не сказал, сколько у него записей, мы не знаем, 100 или 100 миллионов. - person Pondlife; 25.07.2012

У меня была та же проблема, что и в том, как пометить мои старые/архивные записи как «удаленные», потому что они больше не существуют в исходном источнике данных.

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

ГЛАВНАЯ ТАБЛИЦА

ID, NAME, SURNAME, DATE_MODIFIED, ORDERS_COUNT, etc
plus a STATUS column (1 for Active, 0 for Deleted)

TEMP TABLE такая же, как и исходная, но без столбца STATUS.

ID, NAME, SURNAME, DATE_MODIFIED, ORDERS_COUNT, etc

Ключ был в том, чтобы обновить ОСНОВНУЮ ТАБЛИЦУ на STATUS = 0, если идентификатор ОСНОВНОЙ таблицы больше не был во временной таблице. то есть: исходные записи были удалены.

Я сделал это так:

UPDATE m
SET m.Status = 0
FROM tblMAIN AS m
    LEFT JOIN tblTEMP AS t
        ON t.ID = m.ID
WHERE t.ID IS NULL
person Fandango68    schedule 23.10.2018