Está en la página 1de 3

[Aporte][SQL Server 2008] Merge para Insertar o Actualizar

Comunidad Diseo y Programacin Web


Que es lo que se hace cuando en una aplicacin requerimos agregar un registro nuev
o, pero si este ya existe modificarlo con los nuevos datos. Si estas utilizando
SQL Server 2005 o inferior debes escribir 2 o 3 querys, uno para verificar si el
registro existe, si existe entonces actualizas y si no existe lo insertas. En S
QL Server 2008 se han hecho cambios para mejorar esto y ahora en una sola senten
cia puedes hacer esto, insert o update usando la instruccin MERGE.
La instruccin MERGE bsicamente une datos de un resultado de origen establecido en
una tabla destino. Se envan los datos al MERGE, el los compara (por la llave prim
aria), si existe los actualiza y si no existe los ingresa, tambin podra ser que si
no cumple con los requisitos los pueda borrar, insert, update y delete en una s
ola instruccin.
En este primer ejemplo sobre MERGE vamos a hacer el manejo tpico de datos en una
tabla, insert y update.
Tabla que vamos a utilizar de ejemplo.
CREATE TABLE [dbo].[tablaPrueba](
[id] [int] NOT NULL,
[nombre] [varchar](50) NULL,
[fecha_ingreso] [datetime] NULL,
[fecha_actualizacion] [datetime] NULL,
CONSTRAINT [PK_tablaPrueba] PRIMARY KEY CLUSTERED
(
[id] ASC
)

Primero vamos a mostrar como se hace o hacia normalmente en SQL, principalmente


si se utiliza SQL 2005 o inferior.

-- Ejemplo 1 obsoleto pero funcional en SQL 2008 o superior


CREATE PROCEDURE InsertaTablaPrueba(
@id int,
@nombre varchar(50)
)
AS
BEGIN
SET NOCOUNT ON
--Se actualizan los registros en la tabla
UPDATE tablaPrueba
SET nombre = @nombre,
fecha_actualizacion = GETDATE()
WHERE id = @id
--Si no se actualiz ningn registro se inserta en la tabla
IF (@@ROWCOUNT = 0 )
BEGIN
INSERT INTO tablaPrueba (id, nombre, fecha_ingreso, fecha_actualizacion)
VALUES(@id, @nombre, GETDATE(), GETDATE())
END
END

En ese ejemplo podemos ver que se solicitar modificar un registro y si este no a


fect ningn registro (@@ROWCOUNT=0) lo actualiza. En el peor de los casos se ejecut
an dos querys, se toca dos veces la tabla.

-- Ejemplo 2, obsoleto pero funcional en SQL 2008 o superior


CREATE PROCEDURE InsertaTablaPrueba2(
@id int,
@nombre varchar(50)
)
AS
BEGIN
SET NOCOUNT ON
IF EXISTS(SELECT 1 FROM tablaPrueba
WHERE id = @id)
BEGIN
--Se actualizan los registros en la tabla
UPDATE tablaPrueba
SET nombre = @nombre,
fecha_actualizacion = GETDATE()
WHERE id = @id
END
ELSE
BEGIN
--Si no existe el registro se inserta en la tabla
INSERT INTO tablaPrueba (id, nombre, fecha_ingreso, fecha_actualizacion)
VALUES(@id, @nombre, GETDATE(), GETDATE())
END
END

En este ejemplo se consulta si el registro existe, y luego se actualiza o se ins


erta, siempre se toca 2 veces la tabla.
Ahora en el siguiente ejemplo vamos a utilizar MERGE, vamos a ver como en una so
la sentencia se inserta o actualiza un registro, mucho ms eficiente.

-- Ejemplo 3, usando MERGE, mucho ms eficiente


CREATE PROCEDURE InsertaTablaPruebaMerge(
@id int,
@nombre varchar(50)
)
AS
BEGIN
SET NOCOUNT ON
MERGE tablaPrueba as TARGET
USING(SELECT @id, @nombre) AS SOURCE(id, nombre)
ON (TARGET.id = SOURCE.id)
WHEN MATCHED THEN
UPDATE SET nombre = SOURCE.nombre,
fecha_actualizacion = GETDATE()

WHEN NOT MATCHED THEN


INSERT (id, nombre, fecha_ingreso, fecha_actualizacion)
VALUES (SOURCE.id, SOURCE.nombre, GETDATE(), GETDATE());
END

Podemos ver que MERGE recibe una tabla destino, que es a la que se le van a ingr
esar o modificar los datos (TARGET), luego recibe la tabla fuente o los datos fu
ente, en este caso son datos fuente (SOURCE). Luego de estos, cuando los datos c
oncuerdan (WHEN MATCHED) realiza el UPDATE en la tabla, y cuando no existen los
registros (WHEN NOT MATCHED) realiza el INSERT
Datos para probar los 3 procedimientos

EXEC
EXEC
EXEC
EXEC

InsertaTablaPrueba
InsertaTablaPrueba
InsertaTablaPrueba
InsertaTablaPrueba

1,
2,
3,
4,

'Valor
'Valor
'Valor
'Valor

nm.
nm.
nm.
nm.

1'
2'
3'
4'

EXEC InsertaTablaPrueba2 4, 'Valor nm. 4.1'


EXEC InsertaTablaPruebaMerge 5, 'Valor nm. 5'
EXEC InsertaTablaPruebaMerge 3, 'Valor nm. 3.1'
EXEC InsertaTablaPruebaMerge 6, 'Valor nm. 6'
EXEC InsertaTablaPrueba 2, 'Valor nm. 2.1'
SELECT * FROM tablaPrueba

Es evidente que la carga de trabajo en la tabla es mucho menor con la instruccin


MERGE, hacer todo en una sola instruccin es una gran mejora en SQL 2008.

También podría gustarte