私は次のようにテーブルにデータをロードしています:はロールバック戦略対削除 - 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
は同じである必要があります。そうでない場合は、挿入された行を削除する必要があります。
Q1:挿入された行をロールバックするにはどうすればよいでしょうか?
1)はトランザクションでロードを実行し、行数が一致しない場合、ロールバック:
私はアイデアのカップルを持っています。
2)toBeDeleted
という宛先テーブルにフラグ列(ビット)を追加し、ロードを実行し、行カウントが一致しない場合は、1
の値でtoBeDeleted
列を更新して削除の候補としてフラグを立てます。その後、バッチモードで削除します(whileループ)。
または削除しないでください。ただし、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ミルを言わせて。?
質問3:または同様のケースに対してより良い戦略がありますか?
をあなたには、いくつかの後日仕事にロールバックを必要なテーブルAとBの内容は
を変更された可能性があるときにも「あなたはドンT内の他の行があるかもしれません。と仮定すると、
私は、現在のロードだけをロールバックし、履歴はロールバックする必要はありません。だから、通常は毎日ロードします。今日私は日N、明日N + 1を読み込んでいます。したがって、現在のバッチの行数だけがチェックされます。 そして、行数が一致しない場合は、現在のロードのすべてを、一部の行だけでなく、消去する必要があります。 – DNac
これらのシナリオの問題は、あなたが行ったことを元に戻さない限り、実際にはロールバックではありません。単純な行数に依存しているものは間違っている可能性があります。たとえば、行xを複製し、行yをスキップします。あなたの行数は一致します – Ewan
それは本当ですが、その事例は一度も起こっておらず、私はそれが非常にまれであると考えます。 – DNac