web-dev-qa-db-ja.com

SQL Server 2008 MERGE-カウントを取得する最良の方法

Sql ServerのMERGEステートメントからアクションカウントを取得するための最善の方法として、y'allが何を推奨するのかと思います。

つまり、いくつかの挿入、いくつかの更新、いくつかの削除を実行するMERGEを実行します...挿入数、更新数、削除数を確認したい.

これを行うための最良の方法は何でしょうか?

31
eidylon

MERGEステートメントでOUTPUT句を指定して、MERGE中に行われた処理の出力レポートを取得できます。

MERGE (targetTable) AS t 
USING (sourceTable) AS s
ON t.ID = s.ID
WHEN MATCHED THEN
  (some statements)
WHEN NOT MATCHED THEN
  (some statements)
OUTPUT
  $action, inserted.ID 'inserted', deleted.ID 'deleted'
;

これにより、各操作の各「アクション」(挿入、更新、削除)の行が表示されます。ステートメントが多い場合は、OUTPUT INTO @tableVarを実行して、テーブル変数を確認することもできます。

DECLARE @tableVar TABLE (MergeAction VARCHAR(20), InsertedID INT, DeletedID INT)

MERGE (targetTable) AS t 
USING (sourceTable) AS s
ON t.ID = s.ID
WHEN MATCHED THEN
      (some statements)
WHEN NOT MATCHED THEN
      (some statements)
OUTPUT
      $action, inserted.ID 'inserted', deleted.ID 'deleted' INTO @tableVar
;

SELECT MergeAction, COUNT(*) 
FROM @tableVar  
GROUP BY MergeAction

[〜#〜] merge [〜#〜] ステートメントと OUTPUT句 の詳細については、Books Onlineをご覧ください。

マーク

33
marc_s

個々の変数に抽出するには、ピボットを使用してmarc_sによるポストプロセスの回答を得ることができます。

    declare
        @mergeResultsTable table (MergeAction VARCHAR(20));

    declare
        @insertCount int,
        @updateCount int,
        @deleteCount int;

    merge ...
    output $action into @mergeResultsTable; 

    select @insertCount = [INSERT],
           @updateCount = [UPDATE],
           @deleteCount = [DELETE]
      from (select 'NOOP' MergeAction -- row for null merge into null
             union all
            select * from @mergeResultsTable) mergeResultsPlusEmptyRow     
     pivot (count(MergeAction) 
       for MergeAction in ([INSERT],[UPDATE],[DELETE])) 
        as mergeResultsPivot;

Init varsが0であるか、ソースまたはターゲットテーブルに> 0の行があることがわかっている場合、ユニオン 'noop'行を削除できます。

5
crokusek

どうですか:

INSERT YourResultsTable (action, cnt)
SELECT action, count(*)
FROM
(
    MERGE (targetTable) AS t 
    USING (sourceTable) AS s
       ON t.ID = s.ID
    WHEN MATCHED THEN      (some statements)
    WHEN NOT MATCHED THEN      (some statements)
    OUTPUT $action as action, inserted.ID as ins, deleted.ID as del
) m
GROUP BY action;

[編集]わかりましたので、試してください:

INSERT YourResultsTable (action)
SELECT action
FROM
(
    MERGE (targetTable) AS t 
    USING (sourceTable) AS s
       ON t.ID = s.ID
    WHEN MATCHED THEN      (some statements)
    WHEN NOT MATCHED THEN      (some statements)
    OUTPUT $action as action, inserted.ID as ins, deleted.ID as del
) m;

(そして結果を数える)

ロブ

1
Rob Farley