Microsoft SQL Server
UNIR
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 entretargetTable
ysourceTable
. -
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 latargetTable
-
THEN UPDATE
: actualice las columnas del registro coincidente especificadas porSET ....
-
WHEN NOT MATCHED
: acciones a tomar cuando no se encuentra unatargetTable
entargetTable
-
WHEN NOT MATCHED BY SOURCE
: acciones a tomar cuando no se encuentra unasourceTable
en lasourceTable
desourceTable
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ónINSERT
-
UPDATE
acciónUPDATE
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:
dbo.Producto : esta tabla contiene información sobre el producto que la compañía está vendiendo actualmente
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:
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.
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.
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.
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;