Я загрузки данных в таблицу следующим образом:Удалить против Откат стратегии - ETL нагрузки
DECLARE @srcRc INT;
DECLARE @dstRc INT;
SET @srcRc = (SELECT COUNT(*) FROM A)
INSERT INTO t
(Col1
,Col2
,Col3
)
SELECT A.Col1
,A.Col2
,B.Col3
FROM A
JOIN B
ON A.Id = B.Id;
SET @dstRc = @@ROWCOUNT
Теперь я сравниваю переменные @srcRc
и @dstRc
. ROWCOUNT
должны быть одинаковыми. Если это не так, вставленные строки нужно удалить.
Вопрос 1. Какова была бы лучшая стратегия отката вставленных строк?
У меня есть пара идей:
1) Выполнить загрузку в транзакции и отката, если ROWCOUNT не совпадает.
2) Добавьте столбец столбца (бит) в таблицу назначения с именем toBeDeleted
, запустите загрузку и если строка не совпадает, обновите столбец toBeDeleted
с значением 1
, чтобы указать его как кандидата для удаления. Затем удалите в пакетном режиме (while-loop).
Или не удаляйте их, но всегда исключайте удаленные кандидаты из запроса при работе с таблицей t
.
3) Прежде чем вставлять строки, сначала сравните номер строки. Если это не соответствует, не запускайте загрузку.
DECLARE @srcRc INT;
DECLARE @dstRc INT;
SET @srcRc = (SELECT COUNT(1) FROM A);
SET @dstRc = (SELECT COUNT(1) FROM A JOIN B ON A.Id = B.Id);
Q2: Что было бы лучшим решением для большего количества строк, скажем, 10-100 mil.?
Q3: Есть ли какая-нибудь лучшая стратегия для подобного случая?
Мне нужно откат только «текущей» нагрузки, а не истории. Поэтому я обычно загружаю день ото дня. Сегодня я загружаю дату N, завтра N + 1. Таким образом, проверяется только текущая строка строки. И если rowcount не соответствует, все из текущей нагрузки нужно удалить, а не только некоторые из строк. – DNac
проблема с этими сценариями - это не откат, если вы не отмените все, что бы вы ни делали. Все, что полагается на простой подсчет строк, может пойти не так. например, вы дублируете строку x и пропустите строку y. ваш счетчик строк будет соответствовать – Ewan
Это правда, но этого случая никогда не было, и я считаю, что это очень редко. – DNac