Usando la sentencia Merge en SQL Server, How to use Merge SQL Server

| domingo, 12 de julio de 2015


Usando la sentencia Merge en SQL Server, How to use Merge SQL Server

En esta entrada deseo compartir con ustedes el uso de la sentencia Merge, nada nueva por cierto, nació con SQL Server 2008 y lo curioso es que donde he visitado no la conocen del todo y lo que significa que no saben usarla, dicho en pocas palabras esta sentencia nos permite insertar/actualizar/eliminar nuestro registros en una sola instrucción. Osea si el registro no existe lo inserta y si existe actualiza sus campos.

Esta sentencia MERGE nos evita realizar acciones como la que muestro a continuación, tanto a nivel de base de datos como de nuestra aplicación:


If NOT EXISTS(SELECT 1 FROM TuTabla
    WHERE Campo1 = @Parametro1 AND
    Campo2 = @Campo2
   )
  
  BEGIN
  --Insertar nuevo registro
   --INSERT INTO TuTabla(..,..) 
  
  END
ELSE
  BEGIN
  --Actualizar registro existente
   --UPDATE TuTabla
   --SET        
   --WHERE
  END


Como se puede ver en el ejemplo realizamos 2 consultas a la Base de Datos, una para verificar si el registro ya existe y la otra, en caso existiera hacemos un Update caso contrario lo Insertamos, Merge evita esto.

Veamos primero creemos la siguiente Tabla:
 

Código T-SQL para crearla:

USE TEMPDB
GO

IF object_id ('LecturaMedidor') is not null
BEGIN
 DROP TABLE LecturaMedidor;
END

CREATE TABLE [dbo].[LecturaMedidor]
(
 [FechaLectura] date NOT NULL,
 [SerieMedidor] char(10) NOT NULL, 
 [CodZona] [smallint] NULL,
 [Lectura] decimal(18,7) NULL, 
 [Ajuste] decimal(18,7) NULL
);

ALTER TABLE dbo.LecturaMedidor ADD CONSTRAINT
 PK_LecturaMedidor PRIMARY KEY CLUSTERED
 (
 FechaLectura,
 SerieMedidor
 ) 

GO

Ahora creamos un Stored Procedured que se encargue de usar Merge para insertar/actualizar los registros:

USE TEMPDB
GO

CREATE PROCEDURE [dbo].[LecturaMedidorMerge]
(
 @FechaLectura date,
 @SerieMedidor char(10),
 @CodZona smallint,
 @Lectura decimal(18,7),
 @Ajuste decimal(18,7)
)
AS

BEGIN
SET NOCOUNT ON
 
 MERGE LecturaMedidor AS target
    USING (SELECT @FechaLectura, @SerieMedidor, @CodZona, @Lectura, @Ajuste) 
 
 AS source (FechaLectura, SerieMedidor, CodZona, Lectura, Ajuste)
    ON (target.FechaLectura = source.FechaLectura AND 
  target.SerieMedidor = source.SerieMedidor
  )
    WHEN MATCHED THEN      
  UPDATE SET
    CodZona = source.CodZona,
    Lectura = source.Lectura,
    Ajuste = source.Ajuste

 WHEN NOT MATCHED THEN
  INSERT (FechaLectura, SerieMedidor, CodZona, Lectura, Ajuste)
  VALUES
           (source.FechaLectura
           ,source.SerieMedidor
           ,source.CodZona
           ,source.Lectura
           ,source.Ajuste);

END

GO


Ahora realizamos unas pruebas:

USE TEMPDB
GO

SELECT * FROM dbo.LecturaMedidor
GO
--0 rows


--Insertamos 2 registros
EXEC LecturaMedidorMerge '20150701','ABCDF12345',1,1550,0;
EXEC LecturaMedidorMerge '20150702','ABCDF12345',1,1550,0;
SELECT * FROM dbo.LecturaMedidor
--2 rows
--FechaLectura SerieMedidor CodZona Lectura Ajuste
--2015-07-01 ABCDF12345 1 1550.0000000 0.0000000
--2015-07-02 ABCDF12345 1 1550.0000000 0.0000000


--Actualizamos el registro ingresado el 20150701, con nuevo 
--valor de Lectura 2360
EXEC LecturaMedidorMerge '20150701','ABCDF12345',1,2360,0;
SELECT * FROM dbo.LecturaMedidor
WHERE FechaLectura = '20150701'
--1 row modificado
--FechaLectura SerieMedidor CodZona Lectura Ajuste
--2015-07-01 ABCDF12345 1 2360.0000000 0.0000000


Pueden adaptarla de acuerdo a sus escenarios.


Saludos!

0 comentarios:

Publicar un comentario