Una de las novedades que trae SQL Server 2008 respecto a T-SQL es la sentencia MERGE.
Permite seleccionar una tabla origen y una tabla destino y una condición de unión entre las dos tablas. Además de esto permite especificar qué acciones se deben hacer cuando los elementos de una tabla coinciden o no coinciden. Por ejemplo, se puede querer hacer la unión de dos tablas. Si un registro está en las dos tablas actualizar la información pero si no está borrarlo.
La sintaxis es la siguiente: ( Sólo incluyo la parte más representativa para enseñar la funcionalidad. En la ayuda podéis encontrar la versión completa )
[ WITH <common_table_expression> [,…n] ]
MERGE
[ TOP ( expression ) [ PERCENT ] ]
[ INTO ] target_table [ [ AS ] table_alias ]
[ WITH ( <merge_hint> ) ]
USING <table_source>
ON <search_condition>
[ WHEN MATCHED [ AND <search_condition> ]
THEN <merge_matched> ]
[ WHEN [TARGET] NOT MATCHED [ AND <search_condition> ]
THEN <merge_not_matched> ]
[ WHEN SOURCE NOT MATCHED [ AND <search_condition> ]
THEN <merge_ matched> ]
Veamos un par de ejemplos y como no hay que reinventar la rueda, pongo un par de ejemplos de los books-online de SQL Server 2008, que considero que aclaran perfectamente su funcionamiento.
Ejemplo1:
Por ejemplo, un posible uso es para optimizar las operaciones de actualización y borrado de una determina tabla.
En este ejemplo de AdventureWorks se actualiza la tabla de inventario ( ProductInventory ) en función de las órdenes de venta existentes ( SalesOrderDetail ). Se actualiza la columna Quantity, restando el número de ventas que se han hecho del producto en el día. Si el número de elementos es 0, se elimina la fila.
USE AdventureWorks;
GO
MERGE Production.ProductInventory AS pi
USING (SELECT ProductID, SUM(OrderQty) FROM Sales.SalesOrderDetail sod
JOIN Sales.SalesOrderHeader soh
ON sod.SalesOrderID = soh.SalesOrderID
AND soh.OrderDate = GETDATE()
GROUP BY ProductID) AS src (ProductID, OrderQty)
ON (pi.ProductID = src.ProductID)
WHEN MATCHED AND pi.Quantity – src.OrderQty <> 0
THEN UPDATE SET pi.Quantity = pi.Quantity – src.OrderQty
WHEN MATCHED AND pi.Quantity – src.OrderQty = 0
THEN DELETE;
Ejemplo2:
En este segundo ejemplo se utiliza para insertar, actualizar o borrar los datos de una tabla en función de una serie de condiciones.
MERGE Departments AS d
USING Departments_delta AS dd
ON (d.DeptID = dd.DeptID)
WHEN MATCHED AND d.Manager <> dd.Manager OR d.DeptName <> dd.DeptName
THEN UPDATE SET d.Manager = dd.Manager, d.DeptName = dd.DeptName
WHEN NOT MATCHED THEN
INSERT (DeptID, DeptName, Manager)
VALUES (dd.DeptID, dd.DeptName, dd.Manager)
WHEN SOURCE NOT MATCHED THEN
DELETE;
Buena copia al merge de Oracle juasjuasjuas
Buena copia al merge de Oracle juasjuasjuas
En firebird 2 ya existia una mejor, Update or Insert Matching, es mas sencilla la sintaxis