Tal vez algunos ya han utilizado esta sentencia, la ocupamos para
insertar, actualizar o borrar filas de acuerdo a los resultados que se realizan
de la combinación de una tabla con otro origen de datos, esta última puede ser un
CTE, una variable tipo tabla, entre algunas otras.
La sintaxis sería la siguiente, recordemos que el código encerrado por
corchetes es opcional:
MERGE INTO <tablaobjetivo> AS obj USING <tablafuente> AS fuente ON <clausula coincidencia> WHEN MATCHED [ AND < clausula >] THEN < codigo > WHEN NOT MATCHED [BY TARGET] [AND < clausula >] THEN INSERT... WHEN NOT MATCHED BY SOURCE [AND < clausula >] THEN <codigo> [OUTPUT ...]
Ahora veamos para que sirve cada una:
MERGE INTO
<tablaObjetivo> : Define la
tabla a la cual le realizaremos las operaciones INSERT, UPDATE, o DELETE.
USING <tablaFuente>: Define
la tabla de la cual provienen los datos, aunque también se puede utilizar un
CTE o tabla derivada entre algunas otras opciones. Lo más común es utilizar una
tabla.
ON <clausula de
coincidencia>: Define la cláusula utilizada para encontrar las
coincidencias entre ambas tablas, fuente y destino, muy parecido al ON de un JOIN.
WHEN MATCHED [ AND
<clausula>] THEN <codigo>: Se utiliza cuando existen coincidencias
a través de la cláusula ON, por lo
tanto la acción INSERT no está permitida; es posible
utilizar 2 cláusulas WHEN MATCHED,
una para utilizar la acción UPDATE y
otra para la acción DELETE, la única
condicionante es que deben tener filtros si se utilizan ambas, esto se los explicaré con ejemplos
posteriormente.
WHEN NOT MATCHED [BY TARGET] [AND
<clausula>] THEN INSERT... Se utiliza cuando una fila existe
en la fuente pero no en el destino, por lo tanto la única operación permitida es
un INSERT.
WHEN NOT MATCHED BY SOURCE [AND
< clausula >] THEN <codigo> Es el caso contrario a la cláusula
anterior, cuando la fila existe en la tabla destino pero no en la fuente, no se
puede aplicar una operación INSERT pero
si UPDATE y DELETE, también se puede declarar dos cláusulas de este tipo al
igual que la claúsula WHEN MATCHED,
con la misma condicionante que deben tener filtros.
OUTPUT Se pueden obtener
los datos insertados, eliminados y actualizados por medio de las palabras
reservadas inserted y deleted, esto lo expliqué en otro en la
publicación CLAUSULA
OUTPUT( inserted, deleted ) SIN TRIGGERS.
Como nota importante, no es necesario declarar los 3 tipos de WHEN en
nuestra sentencia, solo se requiere una como mínimo para ejecutarla. Ahora
vamos a los ejemplos, los dos ejemplos hacen el mismo proceso, la diferencia
radica en que uno utiliza CTE y el otro una variable tipo tabla:
Ejemplo usando CTE:
IF OBJECT_ID( 'dbo.prueba' ) IS NOT NULL DROP TABLE dbo.prueba CREATE TABLE dbo.prueba ( cve TINYINT , tipo CHAR(1) , edad SMALLINT , nombre VARCHAR(30) , CONSTRAINT pkPrueba PRIMARY KEY ( cve, tipo ) ) INSERT INTO dbo.prueba( cve, tipo, edad, nombre ) VALUES( 1 , 'A' , 30 , 'PEDRO' ) , ( 2 , 'A' , 22 , 'IGNACIO' ) , ( 3 , 'B' , 23 , 'JUAN' ) , ( 4 , 'C' , 20, 'LUIS' ) ;WITH cte AS( SELECT 2 AS cve, 'A' AS tipo, 28 AS edad, 'RAYMUNDO' AS nombre UNION SELECT 3, 'B' , 20 , 'SERGIO' UNION SELECT 4, 'D' , 29 , 'ALBERTO' UNION SELECT 5, 'A' , 29 , 'CARLOS' ) MERGE INTO prueba AS obj USING cte AS fuente ON obj.cve = fuente.cve AND obj.tipo = fuente.tipo WHEN MATCHED AND obj.edad > fuente.edad THEN UPDATE SET obj.tipo = fuente.tipo , obj.edad = fuente.edad , obj.nombre = fuente.nombre WHEN MATCHED AND obj.edad < fuente.edad THEN DELETE WHEN NOT MATCHED BY TARGET THEN INSERT VALUES( fuente.cve, fuente.tipo, fuente.edad, fuente.nombre ) WHEN NOT MATCHED BY SOURCE AND obj.edad <= 25 THEN DELETE WHEN NOT MATCHED BY SOURCE AND obj.edad > 25 THEN UPDATE SET obj.nombre = 'MODIFICADO' OUTPUT $action AS theAction, inserted.* , deleted.* ; SELECT * FROM prueba;
Ejemplo usando variable tipo tabla:
IF OBJECT_ID( 'dbo.prueba' ) IS NOT NULL DROP TABLE dbo.prueba CREATE TABLE dbo.prueba ( cve TINYINT , tipo CHAR(1) , edad SMALLINT , nombre VARCHAR(30) , CONSTRAINT pkPrueba PRIMARY KEY ( cve, tipo ) ) INSERT INTO dbo.prueba( cve, tipo, edad, nombre ) VALUES( 1 , 'A' , 30 , 'PEDRO' ) , ( 2 , 'A' , 22 , 'IGNACIO' ) , ( 3 , 'B' , 23 , 'JUAN' ) , ( 4 , 'C' , 20, 'LUIS' ) DECLARE @t TABLE ( cve TINYINT, tipo CHAR(1), edad SMALLINT, nombre VARCHAR(30) ) INSERT INTO @t SELECT 2 AS cve, 'A' AS tipo, 28 AS edad, 'RAYMUNDO' AS nombre UNION SELECT 3, 'B' , 20 , 'SERGIO' UNION SELECT 4, 'D' , 29 , 'ALBERTO' UNION SELECT 5, 'A' , 29 , 'CARLOS' MERGE INTO prueba AS obj USING @t AS fuente ON obj.cve = fuente.cve AND obj.tipo = fuente.tipo WHEN MATCHED AND obj.edad > fuente.edad THEN UPDATE SET obj.tipo = fuente.tipo , obj.edad = fuente.edad , obj.nombre = fuente.nombre WHEN MATCHED AND obj.edad < fuente.edad THEN DELETE WHEN NOT MATCHED BY TARGET THEN INSERT VALUES( fuente.cve, fuente.tipo, fuente.edad, fuente.nombre ) WHEN NOT MATCHED BY SOURCE AND obj.edad <= 25 THEN DELETE WHEN NOT MATCHED BY SOURCE AND obj.edad > 25 THEN UPDATE SET obj.nombre = 'MODIFICADO' OUTPUT $action AS theAction, inserted.* , deleted.* ; SELECT * FROM prueba;Esto es lo que contiene las tablas fuente y objetivo:
Como podemos observar, las únicas filas que coinciden son las que tienen valores en 2 A y 3 B en las columnas cve y tipo respectivamente. En la siguiente imagen se explica que es lo que realiza dicho MERGE con todas sus cláusulas WHEN
Si tienen alguna duda o comentario al respecto, pueden escribirme.
SALUDOS!
COMPARTE ESTA INFORMACION SI TE PARECIO INTERESANTE
0 comentarios:
Publicar un comentario