Sql Server 2008 MERGE-la mejor manera de obtener recuentos


Me pregunto qué recomendaría y'alls como la mejor manera de obtener los recuentos de acciones de una instrucción MERGE en Sql Server.

Por lo tanto, es decir, corro una FUSIÓN que hace algunos insertos, algunas actualizaciones y algunas eliminaciones,... Me gustaría poder averiguar CUÁNTAS inserciones, CUÁNTAS actualizaciones y Cuántas eliminaciones.

¿Cuál sería la mejor manera de hacer esto?

Author: marc_s, 2009-08-13

3 answers

Puede especificar una cláusula OUTPUT en su sentencia MERGE y obtener un informe de salida de lo que se ha hecho durante la FUSIÓN.

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

Esto le dará una fila para cada "acción" (insertar, actualizar, eliminar) para cada operación. Si se trata de un montón de sentencias, también podría GENERAR EN @tableVar y luego mirar la variable de la tabla.

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

Echa un vistazo a los Libros en línea para obtener detalles sobre la instrucción MERGEy la cláusula OUTPUT.

Marc

 33
Author: marc_s,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-08-12 20:38:32

Para extraer en vars individuales, puede publicar respuesta de proceso por marc_s usando 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;

La fila 'noop' de la unión se puede eliminar si init vars a 0 o sabe que la tabla de origen o destino tiene >0 filas.

 5
Author: crokusek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-23 01:13:35

Qué tal:

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;

[Editar] Ok, así que intenta:

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;

(y luego contar los resultados)

Rob

 1
Author: Rob Farley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-08-13 08:35:26