2012-04-18 15 views
35

を支援するために必要な例をマージ:https://stackoverflow.com/a/2967983/857994からT SQLは以下の理解

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); 

は挿入/更新を行う(といくつかの追加作業を削除)するにはかなり気の利いた方法です。私はいくつかのグーグルの後にもそれを追跡することが困難だと思っています。

誰かがしてくださいすることができ:少し簡単な言葉でこれを説明

  • - MSDNのドキュメントは、この場合には私の脳をバラバラ。
  • ユーザーは、&の金額の値を他のデータベースの場所から選択する代わりに入力することができるように、どのように変更することができますか?

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

+0

私は以下のウォークスルーをしましたが、もし私があなただったら私はここで2番目の質問を投稿しますあなたのターゲットテーブルの構造とXMLソースからのサンプルスニペットを持っているので、どうすればこのxmlからこのテーブルを更新するためのMERGE文を書くでしょうか?また、最後にMERGEステートメントがジョブにとって最適なツールではないかもしれないことに注意してください。 – RThomas

+0

ありがとう、それは私が必要としていたものです。私は余分な質問に後でするかもしれませんが、それは良い提案です。 –

答えて

67

join statementsに精通していない場合は、ここから開始する必要があります。結合がどのように機能するかを理解することが残りの鍵です。ジョインに精通したら、マージを理解することは、マージを行う行と一致しない行に対して何をすべきかを指示する完全な結合として考えることで最も簡単です。

ので、提供されたコードのサンプルを使用して、テーブルcommissions_history

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

を見てみましょうMERGE文は、完全なテーブル間の結合を作成し、「ターゲット」とテーブルを返す式(またはAと呼ばれます「ソース」と呼ばれる、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ですが、default句の代わりに、またはdefault句に加えてnot matched by sourceを指定することができます。マージステートメントは、両方のタイプの不一致(ターゲットにないレコード、またはのソースにないレコード)をサポートしています(on節で定義されています)。 You can find full documentation, restrictions, and complete syntax on MSDN.

+4

偉大な答え、ありがとう! –

+0

'FULL JOIN'はすばらしいことをすることができます! – ErikE

+0

偉大な答え、非常に徹底的。私はトラックを再読みすると明確になるので、いつもBY TARGETまたはBY SOURCEをWHEN NOT MATCHED句で指定するのが好きです。あなたはデフォルトが何であるかを覚える必要はなく、英語に近いです。 – Davos

0

与えられた解答例では、

DECLARE @Request Int 

を行ってきたが、次のようにSQLでそれを呼び出す:

SELECT @amount, @requestID 

は、もう一つは、同一の変数の命名と呼び出すことになります。

@amount vs. Amount -> @Amount & Amount 
関連する問題