2016-04-12 15 views
2

挿入スクリプト(重複を避ける)をバッチしようとしていて、プライマリキーを持たないテーブルがいくつか出てきています(私は知っています...私はそれらを作成せず、 )。基本的には、私が必要とする行をつかんで、一時テーブル([TempTable])に入れ、それらの値をいくつか更新しました。SQL別のレコードを挿入する

[TempTable]から[OriginalTable]までのバッチの値をDISTINCT TOPに再挿入する必要があります。これを行うには、私が作成したtempテーブルのカラムが必要です(これは[ValuesInserted]としましょう)。これはちょうど挿入されたカラムを指定します。

DISTINCTの値をTOPを使用して元のテーブルに格納すると、INSERTの文が実行されます。

INSERT INTO [OriginalTable] 
SELECT DISTINCT TOP (1000) * 
FROM [TempTable] 

次に、ちょうど挿入されたレコードのValuesInsertedを1に設定するようにtempテーブルを更新します。 私がこだわっているところである:

UPDATE /*TOP (1000) - Doesn't work*/ [TempTable] 
SET [ValuesInserted] = 1 
??? 

TOPを使用して)私の次のINSERT文は、レコードの前のセットをキャプチャしないように、そして、私は一時テーブルから、それらのレコードを削除することになります。

DELETE 
FROM [TempTable] 
WHERE [ValuesInserted] = 1 

私がいる主な問題は、ただ単にTOP (1000)行でUPDATEを実行している、[TempTable]で重複を有することができるすべてのレコードをキャプチャしていないということです。 [TempTable]という2つのコピーのすべての列に対してINNER JOINを実行することはできません。これは、動的SQLを使用する多くの異なる表で実行されているためです。基本的には、スクリプトは汎用的である必要があります(テーブルに固有のものではありません)が、プライマリキーが存在しないものと想定してください。

Val1 Val2 ValuesInserted 
1  1  0 
1  2  0 
1  3  0 
1  4  0 
1  5  0 
1  6  0 
1  7  0 
1  8  0 
1  9  0 
1  1  0    <--Duplicate 
2  1  0 
2  2  0 
2  3  0 
2  4  0 
2  5  0 
2  6  0 
2  7  0 
2  8  0 
2  9  0 
2  1  0    <--Duplicate 
3  1  0 
3  2  0 
3  3  0 
3  4  0 
3  5  0 
3  6  0 
3  7  0 
3  8  0 
3  9  0 
3  1  0    <--Duplicate 
1  2  0    <--Duplicate 
1  3  0    <--Duplicate 

のみ最初の5つのレコードが更新されます。この上記のデータセットにUPDATE TOP (5)を行う::私は一致するすべてのレコードを更新する必要があり

Val1 Val2 ValuesInserted 
1  1  1    <--Updated 
1  2  1    <--Updated 
1  3  1    <--Updated 
1  4  1    <--Updated 
1  5  1    <--Updated 
1  6  0 
1  7  0 
1  8  0 
1  9  0 
1  1  0    <--Duplicate 
2  1  0 
2  2  0 
2  3  0 
2  4  0 
2  5  0 
2  6  0 
2  7  0 
2  8  0 
2  9  0 
2  1  0    <--Duplicate 
3  1  0 
3  2  0 
3  3  0 
3  4  0 
3  5  0 
3  6  0 
3  7  0 
3  8  0 
3  9  0 
3  1  0    <--Duplicate 
1  2  0    <--Duplicate 
1  3  0    <--Duplicate 

次の一般的なサンプルでは、​​アイデアをキャプチャ上位5のレコードは次のようになります。

Val1 Val2 ValuesInserted 
1  1  1    <--Updated 
1  2  1    <--Updated 
1  3  1    <--Updated 
1  4  1    <--Updated 
1  5  1    <--Updated 
1  6  0 
1  7  0 
1  8  0 
1  9  0 
1  1  1    <--Updated 
2  1  0 
2  2  0 
2  3  0 
2  4  0 
2  5  0 
2  6  0 
2  7  0 
2  8  0 
2  9  0 
2  1  0    <--Duplicate 
3  1  0 
3  2  0 
3  3  0 
3  4  0 
3  5  0 
3  6  0 
3  7  0 
3  8  0 
3  9  0 
3  1  0    <--Duplicate 
1  2  1    <--Updated 
1  3  1    <--Updated 

このサンプルのアイデアの仕事、私は私の特定のケースに適用することができます。

私はこれに完全に間違っているのですか、何か不足していますか?私は、というリソースを狙っているわけではないというのが、スクリプトがバッチ処理され、インパクトの大きいサーバー上の非常に大きなデータベースで実行されているためです。

これに最も近いトピックは、 Using Distinct in SQL Updateです。 しかし、TOPを使用すると、指定された回答は機能しません。

編集:これは明らかに最初は明らかではありませんでした。私がやっている最初のことは、[OriginalTable]から行をつかんで、[TempTable]に入れることです。これらの行は、最初は一意です。ただし、上記のサンプルのようなデータを生成する値の一部を変更する更新を実行します。から、DISTINCTの行を取得し、[OriginalTable]に再挿入する必要があります。

+0

あなたがここに持っている最大の問題は、あなたがトップを使用しているありますあなたは注文していません。あなたが注文することなく、どの行が選択されるかを決める方法がありません。 https://blogs.msdn.microsoft.com/conor_cunningham_msft/2008/08/27/no-seatbelt-expecting-order-without-order-by/ –

+0

これは[tag:batch-file]にリンクされていません。 .. – aschipfl

答えて

2

これを可能な限り複雑にするためにあなたが実際に行っているように見えます。私はちょうど最初に一時テーブルから重複を削除します。または決してINSERTそこに、それはさらに良いです。 SSISを使用して実際のETLソリューションを構築することもできます。

それらのものは、あなたが探していることはOUTPUT任意のINSERTに追加することができます句、UPDATE、またはDELETE声明で、言った:

DECLARE @inserted_ids TABLE (val1, val2) 

INSERT INTO dbo.OriginalTable (val1, val2) 
OUTPUT INSERTED.val1, INSERTED.val2 INTO @inserted_ids 
SELECT DISTINCT TOP 1000 val1, val2 
FROM dbo.TempTable 

DELETE TT 
FROM @inserte_ids II 
INNER JOIN dbo.TempTable TT ON 
    TT.val1 = II.val1 AND 
    TT.val2 = II.val2 
+0

'[TempTable]'にレコードを挿入すると、それらはすべて一意です。私が言いましたように、「基本的には、必要な行を取得して一時テーブル([TempTable])に入れ、いくつかの値を更新しました。重複したレコードを作成するのはこのアップデートです。 一時テーブルから重複を削除しようとしていますが、これを行う実際のテーブルが大量であるため、バッチで行う必要があります。 –

+0

もしそれらがすべて一意であれば、 'SELECT DISTINCT'の必要はありません。サンプルデータにも重複した値が表示されます。 –

+0

私はSSISソリューションを検討しましたが、ここで書いているスクリプトは、はるかに大きなトランザクションバッチスクリプトの一部です。私は同意する、それは全体的に最良のアプローチではないが、それは私が協力しなければならないことである。 このソリューションも汎用性が必要です。私が言及したように: "基本的には、スクリプトは一般的である必要があります(テーブルには関係ありません)..."。 val1やval2のような特定の列を挙げると、表に固有の列になります。 –

関連する問題