39

以下:

MERGE dbo.commissions_history AS target
USING (SELECT @amount, @requestID) AS source (amount, request)
ON (target.request = source.request)
WHEN MATCHED THEN
    UPDATE SET amount = source.amount
WHEN NOT MATCHED THEN
    INSERT (request, amount)
    VALUES (source.request, source.amount);

https://stackoverflow.com/a/2967983/857994からは、挿入/更新を行う(およびいくつかの追加作業で削除する)かなり気の利いた方法です。グーグルで調べた後でも、フォローするのは難しいと思います。

誰かお願いできますか:

  • これを簡単な言葉で説明してください - この場合、MSDN のドキュメントは私の脳を傷つけました。
  • 別のデータベースの場所から選択する代わりに、ユーザーが金額と要求の値を入力できるように変更する方法を教えてください。

基本的に、これを使用して、取得している XML ファイルから取得した情報を使用して C# アプリから挿入/更新したいと考えています。そのため、このメカニズムを使用して、解析されたデータをデータベースに取得するためにクエリを手動で作成する方法を理解する必要があります。

4

2 に答える 2

75

結合ステートメントに慣れていない場合は、そこから始める必要があります。結合がどのように機能するかを理解することが残りの鍵です。結合に慣れたら、一致する行または一致しない行に対して何をすべきかについての指示を含む完全な結合と考えると、マージを理解するのが最も簡単になります。

提供されているコード サンプルを使用して、テーブル Commissions_history を見てみましょう。

|  Amount  |   Request  |   <other fields> |
--------------------------------------------
|  12.00   |   1234     |   <other data>   |
|  14.00   |   1235     |   <other data>   |
|  15.00   |   1236     |   <other data>   |

merge ステートメントは、「ターゲット」と呼ばれるテーブルと、「ソース」と呼ばれるテーブル (または CTE のようなテーブルに論理的に非常に類似した結果セット) を返す式との間の完全な結合を作成します。

与えられた例では、変数をソースとして使用しています。これは、ユーザーによって設定されているか、パラメーターとして渡されていると想定しています。

DECLARE @Amount Decimal = 18.00;
DECLARE @Request Int = 1234;

MERGE dbo.commissions_history AS target       
USING (SELECT @amount, @requestID) AS source (amount, request)       
ON (target.request = source.request)   

結合と考えると、次の結果セットが作成されます。

|  Amount  |   Request  |   <other fields> | Source.Amount | Source.Request  |
------------------------------------------------------------------------------
|  12.00   |   1234     |   <other data>   |   18.00       |     1234        |
|  14.00   |   1235     |   <other data>   |   null        |     null        |
|  15.00   |   1236     |   <other data>   |   null        |     null        |

一致が見つかったという条件でターゲットに何をすべきかについて与えられた指示を使用する。

WHEN MATCHED THEN        
UPDATE SET amount = source.amount    

結果のターゲット テーブルは次のようになります。リクエスト 1234 の行は 18 に更新されます。

|  Amount  |   Request  |   <other fields> |
--------------------------------------------
|  18.00   |   1234     |   <other data>   |
|  14.00   |   1235     |   <other data>   |
|  15.00   |   1236     |   <other data>   |

一致が見つかったため、他に何も起こりません。しかし、ソースからの値はこのようなものだったとしましょう。

DECLARE @Amount Decimal = 18.00;
DECLARE @Request Int = 1239;

結果の結合は次のようになります。

|  Amount  |   Request  |   <other fields> | Source.Amount | Source.Request  |
------------------------------------------------------------------------------
|  12.00   |   1234     |   <other data>   |   null        |     null        |
|  14.00   |   1235     |   <other data>   |   null        |     null        |
|  15.00   |   1236     |   <other data>   |   null        |     null        |
|  null    |   null     |   null           |   18.00       |     1239        |

一致する行がターゲットで見つからなかったため、ステートメントは他の句を実行します。

WHEN NOT MATCHED THEN                                 
INSERT (request, amount)                                 
VALUES (source.request, source.amount);  

ターゲット テーブルは次のようになります。

|  Amount  |   Request  |   <other fields> |
--------------------------------------------
|  12.00   |   1234     |   <other data>   |
|  14.00   |   1235     |   <other data>   |
|  15.00   |   1236     |   <other data>   |
|  18.00   |   1239     |   <other data>   |

マージ ステートメントの真の可能性は、ソースとターゲットが両方とも大きなテーブルである場合です。単一の単純なステートメントで各行に対して大量の更新および/または挿入を実行できるためです。

最後のメモ。not matchedデフォルトは完全な句ですが、デフォルト句の代わりに、またはデフォルト句に加えてnot matched by target指定できることに注意してください。merge ステートメントは、両方のタイプの不一致 ( on 句で定義されているようにnot matched by source、ソース内のレコードがターゲット内にない、またはターゲット内のレコードがソース内にない) をサポートします。 MSDN で完全なドキュメント、制限、および完全な構文を見つけることができます。

于 2012-04-18T23:28:11.533 に答える
0

あなたが行った与えられた答えの例では

DECLARE @Request Int

ですが、次のように SQL で呼び出します。

SELECT @amount, @requestID

もう 1 つは、変数の名前付けと呼び出しをまったく同じにすることです。

@amount vs. Amount -> @Amount & Amount
于 2015-05-11T10:19:16.600 に答える