Buscar..


Introducción

A partir de SQL Server 2008, es posible realizar operaciones de inserción, actualización o eliminación en una sola declaración utilizando la instrucción MERGE.

La declaración MERGE le permite unir un origen de datos con una tabla o vista de destino y, a continuación, realizar varias acciones contra el destino en función de los resultados de esa unión.

Sintaxis

  • Según MSDN: https://msdn.microsoft.com/en-us/library/bb510625.aspx [WITH <common_table_expression> [, ... n]] MERGE [TOP (expresión) [PERCENT]] [INTO] < target_table> [WITH (<merge_hint>)] [[AS] table_alias] USING <table_source> ON <merge_search_condition> [WHEN MATCHED [AND <clause_search_condition>] THEN <merge_matched>] [... n] [WHEN NOT MATCHED [BY OBJETIVO] [AND <clause_search_condition>] LUEGO <merge_not_matched>] [CUANDO NO SE AJUSTE POR FUENTE [AND <clause_search_condition>] LUEGO <merge_matched>] [... n] [<output_clause>] [OPTION (<query_matched>]. ..n])]; <target_table> :: = {[database_name. nombre_esquema. | nombre_esquema. ] target_table} <merge_hint> :: = {{[<table_hint_limited> [, ... n]] [[,] INDEX (index_val [, ... n])]}} <table_source> :: = {table_or_view_name [ [AS] table_alias] [<tablesample_clause>] [WITH (table_hint [[,] ... n])] | rowset_function [[AS] table_alias] [(bulk_column_alias [, ... n])] | user_defined_function [[AS] table_alias] | OPENXML <openxml_clause> | tabla_de_ derivada [AS] table_alias [(column_alias [, ... n])] | <joined_table> | <pivoted_table> | <unpivoted_table>} <merge_search_condition> :: = <search_condition> <merge_matched> :: = {UPDATE SET <set_clause> | DELETE} <set_clause> :: = SET {column_name = {expresión | Por defecto | Nulo} | {udt_column_name. {{property_name = expresión | field_name = expresión} | nombre_método (argumento [, ... n])}} | column_name {.WRITE (expresión, @Offset, @Length)} | @variable = expresión | @variable = columna = expresión | nombre_columna {+ = | - = | * = | / = | % = | & = | ^ = | | =} expresión | @variable {+ = | - = | * = | / = | % = | & = | ^ = | | =} expresión | @variable = columna {+ = | - = | * = | / = | % = | & = | ^ = | | =} expresión} [, ... n] <merge_not_matched> :: = {INSERT [(column_list)] {VALUES (values_list) | VALORES POR DEFECTO}} <clause_search_condition> :: = <search_condition> :: = {[NOT] | (<search_condition>)} [{AND | O} [NO] {| (<search_condition>)}] [, ... n] :: = {expresión {= | <> | ! = |

    | > = | ! > | <| <= | ! <} expresión | string_expression [NO] LIKE string_expression [ESCAPE 'escape_character'] | expresión [NO] ENTRE expresión Y expresión | expresión es [no] nula | CONTIENE ({columna | *}, '<contiene_condición_de_búsqueda>') | FREETEXT ({column | *}, 'freetext_string') | expresión [NOT] IN (subconsulta | expresión [, ... n]) | expresión {= | <> | ! = | | > = | ! > | <| <= | ! <} {TODOS | Algunos | ANY} (subconsulta) | EXISTS (subquery)} <output_clause> :: = {[OUTPUT <dml_select_list> INTO {@table_variable | output_table} [(column_list)]] [OUTPUT <dml_select_list>]} <dml_select_list> :: = {<column_name> | scalar_expression} [[AS] column_alias_identifier] [, ... n] <column_name> :: = {DELETED | Insertado | from_table_name}. {* | nombre_columna} | $ acción

Observaciones

Realiza operaciones de inserción, actualización o eliminación en una tabla de destino en función de los resultados de una unión con una tabla de origen. Por ejemplo, puede sincronizar dos tablas insertando, actualizando o eliminando filas en una tabla en función de las diferencias encontradas en la otra tabla.

MERGE para insertar / actualizar / eliminar

MERGE INTO targetTable

USING sourceTable 
ON (targetTable.PKID = sourceTable.PKID)

WHEN MATCHED AND (targetTable.PKID > 100) THEN
    DELETE

WHEN MATCHED AND (targetTable.PKID <= 100) THEN 
    UPDATE SET 
        targetTable.ColumnA = sourceTable.ColumnA, 
        targetTable.ColumnB = sourceTable.ColumnB

WHEN NOT MATCHED THEN
    INSERT (ColumnA, ColumnB) VALUES (sourceTable.ColumnA, sourceTable.ColumnB);

WHEN NOT MATCHED BY SOURCE THEN
    DELETE
; --< Required

Descripción:

  • MERGE INTO targetTable - tabla a modificar
  • USING sourceTable - fuente de datos (puede ser una tabla o una vista o una función con valores de tabla)
  • ON ... : condición de unión entre targetTable y sourceTable .
  • WHEN MATCHED - acciones a tomar cuando se encuentra una coincidencia
    • AND (targetTable.PKID > 100) - condición (es) adicional (es) que deben cumplirse para que la acción se realice
  • THEN DELETE : eliminar registro coincidente de la targetTable
  • THEN UPDATE : actualice las columnas del registro coincidente especificadas por SET ....
  • WHEN NOT MATCHED : acciones a tomar cuando no se encuentra una targetTable en targetTable
  • WHEN NOT MATCHED BY SOURCE : acciones a tomar cuando no se encuentra una sourceTable en la sourceTable de sourceTable

Comentarios:

Si no se necesita una acción específica, omita la condición, por ejemplo, eliminar WHEN NOT MATCHED THEN INSERT evitará que se inserten registros

La declaración de fusión requiere un punto y coma de terminación.

Restricciones:

  • WHEN MATCHED no permite la acción INSERT
  • UPDATE acción UPDATE puede actualizar una fila solo una vez. Esto implica que la condición de unión debe producir coincidencias únicas.

Combinar usando la fuente CTE

WITH SourceTableCTE AS
(
    SELECT * FROM SourceTable
)
MERGE  
 TargetTable AS target
USING SourceTableCTE AS source  
ON (target.PKID = source.PKID)
WHEN MATCHED THEN     
    UPDATE SET target.ColumnA = source.ColumnA
WHEN NOT MATCHED THEN
    INSERT (ColumnA) VALUES (Source.ColumnA);

MERGE usando la tabla de fuente derivada

MERGE INTO TargetTable  AS Target  
USING (VALUES (1,'Value1'), (2, 'Value2'), (3,'Value3'))  
       AS Source (PKID, ColumnA)  
ON Target.PKID = Source.PKID 
WHEN MATCHED THEN 
    UPDATE SET target.ColumnA= source.ColumnA
WHEN NOT MATCHED THEN
    INSERT (PKID, ColumnA) VALUES (Source.PKID, Source.ColumnA);

Ejemplo de combinación: sincronizar origen y tabla de destino

Para ilustrar la declaración MERGE, considere las siguientes dos tablas:

  1. dbo.Producto : esta tabla contiene información sobre el producto que la compañía está vendiendo actualmente

  2. dbo.ProductNew : esta tabla contiene información sobre el producto que la compañía venderá en el futuro.

El siguiente T-SQL creará y llenará estas dos tablas

IF OBJECT_id(N'dbo.Product',N'U') IS NOT NULL 
DROP TABLE dbo.Product
GO

CREATE TABLE dbo.Product (
ProductID INT PRIMARY KEY,
ProductName NVARCHAR(64),
PRICE MONEY
)

IF OBJECT_id(N'dbo.ProductNew',N'U') IS NOT NULL 
DROP TABLE dbo.ProductNew
GO

CREATE TABLE dbo.ProductNew (
ProductID INT PRIMARY KEY,
ProductName NVARCHAR(64),
PRICE MONEY
)

INSERT INTO dbo.Product VALUES(1,'IPod',300)
,(2,'IPhone',400)
,(3,'ChromeCast',100)
,(4,'raspberry pi',50)

INSERT INTO dbo.ProductNew VALUES(1,'Asus Notebook',300)
,(2,'Hp Notebook',400)
,(3,'Dell Notebook',100)
,(4,'raspberry pi',50)

Ahora, supongamos que queremos sincronizar la tabla de destino dbo.Product con la tabla dbo.ProductNew. Aquí está el criterio para esta tarea:

  1. El producto que existe tanto en la tabla de origen dbo.ProductNew como en la tabla de destino dbo.Product se actualizan en la tabla de destino dbo.Product con nuevos productos nuevos.

  2. Cualquier producto en la tabla de origen dbo.ProductNew que no existe en la tabla de destino dob.Product se inserta en la tabla de destino dbo.Product.

  3. Cualquier producto en la tabla de destino de dbo.Product que no exista en la tabla de origen dbo.ProductNew debe eliminarse de la tabla de destino de dbo.Product. Aquí está la declaración MERGE para realizar esta tarea.

MERGE dbo.Product AS SourceTbl 
USING dbo.ProductNew AS TargetTbl ON (SourceTbl.ProductID = TargetTbl.ProductID)
WHEN MATCHED 
            AND SourceTbl.ProductName <> TargetTbl.ProductName
            OR SourceTbl.Price <> TargetTbl.Price
    THEN UPDATE SET SourceTbl.ProductName = TargetTbl.ProductName,
                SourceTbl.Price = TargetTbl.Price
WHEN NOT MATCHED 
    THEN INSERT (ProductID, ProductName, Price)
         VALUES (TargetTbl.ProductID, TargetTbl.ProductName, TargetTbl.Price)
WHEN NOT MATCHED BY SOURCE 
    THEN DELETE
OUTPUT $action, INSERTED.*, DELETED.*;

Nota: el punto y coma debe estar presente al final de la sentencia MERGE. introduzca la descripción de la imagen aquí

Fusionar utilizando EXCEPTO

Use EXCEPTO para evitar actualizaciones de registros sin cambios

MERGE TargetTable targ
USING SourceTable AS src
    ON src.id = targ.id
WHEN MATCHED
    AND EXISTS (
        SELECT src.field
        EXCEPT
        SELECT targ.field
        )
    THEN
        UPDATE
        SET field = src.field
WHEN NOT MATCHED BY TARGET
    THEN
        INSERT (
            id
            ,field
            )
        VALUES (
            src.id
            ,src.field
            )
WHEN NOT MATCHED BY SOURCE
    THEN
        DELETE;


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow