【问题标题】:Sql Server 2008 MERGE - best way to get countsSql Server 2008 MERGE - 获取计数的最佳方式
【发布时间】:2010-11-19 02:28:32
【问题描述】:

我想知道你们会推荐什么作为从 Sql Server 中的 MERGE 语句中获取操作计数的最佳方法。

所以,即我运行一个 MERGE,它执行一些插入、一些更新和一些删除,...我希望能够找出多少插入、多少更新和多少删除。

最好的方法是什么?

【问题讨论】:

    标签: sql-server sql-server-2008 merge rowcount


    【解决方案1】:

    要提取到单个变量中,可以通过 marc_s 使用 pivot 发布过程答案:

        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 行,则可以删除 union 'noop' 行。

    【讨论】:

      【解决方案2】:

      怎么样:

      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;
      

      (然后统计结果)

      罗伯

      【讨论】:

      • 否:消息 10717,级别 15,状态 1,第 48 行当 FROM 子句包含嵌套的 INSERT、UPDATE、DELETE 或 MERGE 语句时,不允许使用 GROUP BY 子句。
      • 在 SQL Server 2008 开发人员版上测试
      • 我使用了您的编辑,然后使用您插入的表格并使用案例陈述将各个操作汇总到 SUM-Totals 中并记录这些结果。效果很好! SQL Server 强迫我将合并结果插入表变量而不是直接在最外层的 Select 中聚合和设置我的 int 变量,这很糟糕。
      【解决方案3】:

      您可以在 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 clause 的详细信息。

      马克

      【讨论】:

      • 是否有可能在一个语句中以某种方式做到这一点,可能与 group by?这样输出位就会类似于 > OUTPUT $ACTION, COUNT(1) GROUP BY $ACTION ?
      • 不,你不能这样做。您可以只输出到 SSMS 输出窗口,也可以输出到表变量中 - 不要过度拉伸 OUTPUT 子句! :-)
      • 嗯...实际上,OUTPUT 输出的是表变量还是结果集?是否可以在 SELECT 语句中使用 OUTPUT 子句包装 MERGE 语句作为源(作为子查询),然后让外部 SELECT 进行聚合? ...听起来可能。我可能不得不玩这个。
      • OUTPUT 可以将其输出直接发送到 SSMS 中的结果网格,或发送到表变量中 - 就是这样,根据 MSDN 库。你不能做任何你想做的诡计 - 你必须使用我展示的步骤 - 抱歉,你正在尝试做一些 SQL Server 不支持的事情
      • 您似乎无法在 SELECT * FROM (MERGE as a subselect) 或公用表表达式 (WITH MergeOutput AS (MERGE:......)SELECT MergeAction. ....) - 它只是不那样工作。您可以将值输出到输出窗口、表变量或新表(在磁盘上) - 但不能直接将其用作输出结果集。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多