2016-12-07 9 views
4

私は次のようにテーブルにデータをロードしています:はロールバック戦略対削除 - 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内の他の行があるかもしれません。と仮定すると、

答えて

0

OK、ロールバックの一部として削除したくありません。

あなたは確実にAとBからそのリストを再生成することができず、あなただけの次の2つの方法

でこれを行うことができますT

からすべてを削除カントとして、あなたは、あなたが挿入された行のリストを保持しなければなりません

  • インポートを変更すると、最初にインポートテーブルに行が挿入されるため、インポートテーブルが不要になるまで、インポートテーブルがハングアップします。

  • は[importId]そこにあなたは明らかに最初の戦略は、より多くのディスクスペースを使用して一意に識別する値

を置くTに余分な列を追加します。したがって、データを保存する時間が長くなればなるほど、余分な列の見栄えが向上します。

別のオプションとして、インポートされたデータのリストを別々に生成し、トランザクションSQLをすべてのデータがSQLにハードコードされた一括挿入にすることができます。

これは、小さなリスト、初期設定データなどに適しています。


編集:

あなたのコメントから、あなたが戻ってそれ自体はロールを望んでいないように聞こえます。しかし、ビジネスロジックをインポートプロセスの周りに適用する最善の方法です。

この場合、3番目の回答が最適です。ソースデータが間違っていることがわかっている場合は、インポートを行わないでください。

+0

私は、現在のロードだけをロールバックし、履歴はロールバックする必要はありません。だから、通常は毎日ロードします。今日私は日N、明日N + 1を読み込んでいます。したがって、現在のバッチの行数だけがチェックされます。 そして、行数が一致しない場合は、現在のロードのすべてを、一部の行だけでなく、消去する必要があります。 – DNac

+0

これらのシナリオの問題は、あなたが行ったことを元に戻さない限り、実際にはロールバックではありません。単純な行数に依存しているものは間違っている可能性があります。たとえば、行xを複製し、行yをスキップします。あなたの行数は一致します – Ewan

+0

それは本当ですが、その事例は一度も起こっておらず、私はそれが非常にまれであると考えます。 – DNac