
Comparando Merge con Store Procedures individuales
La instrucción Merge realiza instrucciones de inserción de registros, actualización o eliminación de registros en una tabla de destino en la misma base de datos o en otra base de datos según los resultados de combinar los registros con una tabla de origen, esta tabla origen puede ser una consulta Select.
Merge puede ser usado de varias formas, en este artículo se hará la comparación de usar Merge que haga el trabajo de inserción y de modificación en el mismo procedimiento con el uso de procedimientos individuales para cada operación.
Para más información ver:
Merge en SQL Server
Usando Merge con Select
Merge en Graph Tables
OutPut en Merge
Procedimientos almacenados
Variables en SQL Server
Insertar registros
Actualización de registros
Ejercicios
Usando la base de datos Northwind
use Northwind
go
Ejercicio 1
En este primer ejercicio se crea un procedimiento almacenado que evalua la existencia de un Cliente, si el cliente existe se van a actualizar sus datos y si no existe se va a insertar un nuevo cliente. En este procedimiento se usa la instrucción Merge con un Select.
Create or alter procedure spClientesActualizaInsertaMerge
(
@Codigo nchar(5),
@Nombre nvarchar(40),
@Contacto nvarchar(30),
@Cargo nvarchar(30),
@Direccion nvarchar(60),
@Ciudad nvarchar(15),
@Region nvarchar(15),
@CodigoPostal nvarchar(10),
@Pais nvarchar(15),
@Fono nvarchar(24),
@Fax nvarchar(24)
)
As
MERGE dbo.Customers As ClientesDestino
USING
(
SELECT @Codigo, @Nombre, @Contacto, @Cargo, @Direccion,
@Ciudad, @Region, @CodigoPostal, @Pais, @Fono, @Fax)
As ClientesOrigen
([CustomerID], [CompanyName], [ContactName], [ContactTitle], [Address],
[City], [Region], [PostalCode], [Country], [Phone], [Fax])
ON ClientesDestino.CustomerId = ClientesOrigen.CustomerId
WHEN MATCHED then -- Cliente encontrado
UPDATE
SET [CustomerID]=ClientesOrigen.[CustomerID],
[CompanyName]=ClientesOrigen.[CompanyName],
[ContactName]=ClientesOrigen.[ContactName],
[ContactTitle]=ClientesOrigen.[ContactTitle],
[Address]=ClientesOrigen.[Address],
[City]=ClientesOrigen.[City],
[Region]=ClientesOrigen.[Region],
[PostalCode]=ClientesOrigen.[PostalCode],
[Country]=ClientesOrigen.[Country],
[Phone]=ClientesOrigen.[Phone],
[Fax]=ClientesOrigen.[Fax]
WHEN NOT MATCHED THEN -- Cliente no encontrado
INSERT VALUES
(@Codigo, @Nombre, @Contacto, @Cargo, @Direccion,
@Ciudad, @Region, @CodigoPostal, @Pais, @Fono, @Fax);
go
Listado de los clientes, se puede ver que el cliente con el que se va a ejecutar el SP no existe. Note que el cliente con ID BBC45 no existe.
Select * from dbo.customers
go
El resultado se muestra en la siguiente imagen

Ejecutar el SP con un nuevo cliente.
Los datos del nuevo cliente son:
Codigo = 'BBC45'
Nombre = 'Black Software Ingenieros'
Contacto = 'FERNANDO LUQUE SANCHEZ'
Cargo = 'Gerente de Procesos'
Direccion = 'Av. Arequipa 9494'
Ciudad = 'Lima'
Region = 'CE'
CodigoPostal = '11580'
Pais = 'Perú'
Fono = '949483333'
Fax = '052-525258'
Ejecutando el procedimiento almacenado.
Execute spClientesActualizaInsertaMerge
@Codigo = 'BBC45',
@Nombre = 'Black Software Ingenieros',
@Contacto = 'FERNANDO LUQUE SANCHEZ',
@Cargo = 'Gerente de Procesos',
@Direccion = 'Av. Arequipa 9494',
@Ciudad = 'Lima',
@Region = 'CE',
@CodigoPostal = '11580',
@Pais = 'Perú' ,
@Fono = '949483333',
@Fax = '052-525258'
go
Listado de los clientes
select * from dbo.customers
go
El resultado se muestra en la siguiente imagen

Ejecutamos el SP con el mismo código del cliente pero con algunos datos cambiados.
Execute spClientesActualizaInsertaMerge
@Codigo = 'BBC45',
@Nombre = 'Black Software Apps',
@Contacto = 'FERNANDO LUQUE SANCHEZ',
@Cargo = 'Gerente General',
@Direccion = 'Av. Guardia Civil 189',
@Ciudad = 'Lima',
@Region = 'CE',
@CodigoPostal = '11900',
@Pais = 'Perú' ,
@Fono = '949363636',
@Fax = '052-115511'
go
Listado de los clientes
select * from dbo.customers
go
El resultado se muestra en la siguiente imagen
Note que se han actualizado el nombre del cliente, el cargo, la dirección, el código postal, el teléfono y el fax.

Ejercicio 2
Usando procedimientos almacenados individuales, uno para la inserción y otro para la actualización de datos, luego estos procedimientos se va a comparar con el use del procedimiento del ejercicio 1 para ver cual es mas eficiente.
Procedimiento para insertar un registro.
Create or alter procedure spClientesInserta
(
@Codigo nchar(5),
@Nombre nvarchar(40),
@Contacto nvarchar(30),
@Cargo nvarchar(30),
@Direccion nvarchar(60),
@Ciudad nvarchar(15),
@Region nvarchar(15),
@CodigoPostal nvarchar(10),
@Pais nvarchar(15),
@Fono nvarchar(24),
@Fax nvarchar(24)
)
As
INSERT into dbo.Customers
([CustomerID], [CompanyName], [ContactName], [ContactTitle], [Address],
[City], [Region], [PostalCode], [Country], [Phone], [Fax])
VALUES
(@Codigo, @Nombre, @Contacto, @Cargo, @Direccion,
@Ciudad, @Region, @CodigoPostal, @Pais, @Fono, @Fax);
go
Ejecutando el procedimiento almacenado
Execute spClientesInserta
@Codigo = 'ILC24',
@Nombre = 'ACW Contratistas',
@Contacto = 'Ingrid Llanos',
@Cargo = 'CEO',
@Direccion = 'Av. Los Laureles 4995',
@Ciudad = 'Lima',
@Region = 'CE',
@CodigoPostal = '52525',
@Pais = 'Perú' ,
@Fono = '969694947',
@Fax = '052-365263'
go
Procedimiento para modificar los datos de un registro.
Create or alter procedure spClientesActualiza
(
@Codigo nchar(5),
@Nombre nvarchar(40),
@Contacto nvarchar(30),
@Cargo nvarchar(30),
@Direccion nvarchar(60),
@Ciudad nvarchar(15),
@Region nvarchar(15),
@CodigoPostal nvarchar(10),
@Pais nvarchar(15),
@Fono nvarchar(24),
@Fax nvarchar(24)
)
As
UPDATE dbo.Customers
SET [CompanyName]=@Nombre,
[ContactName]=@Contacto,
[ContactTitle]=@Cargo,
[Address]=@Direccion,
[City]=@Ciudad,
[Region]=@Region,
[PostalCode]=@CodigoPostal,
[Country]=@Pais,
[Phone]=@Fono,
[Fax]=@Fax
where [CustomerID]=@Codigo
go
Ejecutando el procedimiento almacenado para actualizar los datos de un cliente.
Execute spClientesActualiza
@Codigo = 'ILC24',
@Nombre = 'ACW Contratistas',
@Contacto = 'Ing. Esmeralda Sandoval Wong',
@Cargo = 'Administrador',
@Direccion = 'Av. San Pablo 4995',
@Ciudad = 'Lima',
@Region = 'CE',
@CodigoPostal = '45154',
@Pais = 'Perú' ,
@Fono = '969694947',
@Fax = '052-365263'
go
Listado de clientes, se puede ver el cliente nuevo.
select * from dbo.customers
go
El resultado se muestra en la siguiente imagen

Comparando los Costos de ejecución de cada opción
Para mostrar el costo del uso de cada opción se insertará el mismo registro, obviamente después de usar Merge se procede a borrar el registro para ejecutar el SP que inserta el registro, mostrando para cada caso el tiempo de ejecución usando el Plan de ejecución estimado.
Insertar un registro con Merge
Execute spClientesActualizaInsertaMerge
@Codigo = 'ABC96',
@Nombre = 'ThunderApps Co.',
@Contacto = 'Leo Campos Guevara',
@Cargo = 'Gerente Comercial',
@Direccion = 'Av. Ciro Alegría 575',
@Ciudad = 'Trujillo',
@Region = 'CE',
@CodigoPostal = '54858',
@Pais = 'Perú' ,
@Fono = '949422112',
@Fax = '052-36362'
go
El Plan de ejecución estimado con el costo se muestra en la imagen siguiente

Note que el costo es: 0.153338
Borramos el registro para insertarlo con el SP individual.
delete dbo.Customers where CustomerID = 'ABC96'
go
Insertar el registro con el SP individual de inserción creado llamado spClientesInserta
Execute spClientesInserta
@Codigo = 'ABC96',
@Nombre = 'ThunderApps Co.',
@Contacto = 'Leo Campos Guevara',
@Cargo = 'Gerente Comercial',
@Direccion = 'Av. Ciro Alegría 575',
@Ciudad = 'Trujillo',
@Region = 'CE',
@CodigoPostal = '54858',
@Pais = 'Perú' ,
@Fono = '949422112',
@Fax = '052-36362'
go
El Plan de ejecución estimado con el costo se muestra en la imagen siguiente

Note que el costo es: 0.0500062
Comparando:
Costo usando SP con Merge para insertar: 0.1533380
Costo usando SP individual al insertar: 0.0500062
Definitivamente la mejor opción es trabajar con SP sin Merge para la acción de insertar.
Actualizar los datos del cliente
Usando el SP con Merge llamado spClientesActualizaInsertaMerge, el cliente con código ABC96 si existe.
Execute spClientesActualizaInsertaMerge
@Codigo = 'ABC96',
@Nombre = 'ThunderApps Co.',
@Contacto = 'Fernando León Llanos',
@Cargo = 'Gerente de Marketing',
@Direccion = 'Av. Dinamarca 22441',
@Ciudad = 'Trujillo',
@Region = 'CE',
@CodigoPostal = '54858',
@Pais = 'Perú' ,
@Fono = '94959697',
@Fax = '052-12128'
go
El Plan de ejecución estimado con el costo se muestra en la imagen siguiente

Note que el costo es: 0.153338
Actualizar el registro usando el SP llamado spClientesActualiza
Execute spClientesActualiza
@Codigo = 'ABC96',
@Nombre = 'ThunderApps Co.',
@Contacto = 'Fernando León Sánchez',
@Cargo = 'Gerente de Finanzas',
@Direccion = 'Av. Mónaco 46655',
@Ciudad = 'Trujillo',
@Region = 'CE',
@CodigoPostal = '11300',
@Pais = 'Perú' ,
@Fono = '949798953',
@Fax = '052-36363'
go
El Plan de ejecución estimado con el costo se muestra en la imagen siguiente

Note que el costo es: 0.0532883
Comparando la opción de modificación:
Costo usando SP con Merge para insertar: 0.1533380
Costo usando SP individual al insertar: 0.0532883
Definitivamente la mejor opción es trabajar con SP sin Merge para la acción de modificar.