Merge Statement–Um ótimo recurso !

Posted on outubro 7, 2011

2


Como todos nós sabemos o SQL Server 2008 veio com diversas novidades para nos ajudar, sendo assim o produto foi tocado em todas as partes, tanto na parte de BI, Administração e Desenvolvimento. Dentre várias novidades um novo recurso para a otimização de código, facilidade, produtividade e fácil entendimento tivemos o Merge Statement.

Nas versões anteriores do produto SQL Server, quando precisávamos por exemplo comparar tabelas para realizar uma inserção, deleção ou atualização de registros utilizavamos Insert/Update/Delete, muito das vezes realizando uma procedure que comparava os dados por um IF ou outra estrutura de comparação que assim as efetuava. Com a novidade desse novo recurso, podemos agora realizar as 3 opções dentro de uma só declaração.

O merge é um recurso que possibilita a integração dando a habilidade de comparar linha a linha informações entre tabela fonte (Source Table) e tabela de destino (Destination Table).

Sintaxe…

image

Vamos entender melhor a construção dessa sintaxe:

[INTO] = Esse comando se refere a tabela/View de destino ou seja  (Target Table) .

[USING] = Define a tabela/view na qual será baseado as informações para assim realizar as operações de DML  dentro da tabela de destino .

[ON] = Condição que especifica a comparação das informações, funciona como um JOIN. Lembrando que aqui você pode especificar operadores como AND e outros para assim complementar sua condição de satisfação.

[WHEN MATCHED THEN] = Essa é a ação que será realizada quando a cláusula ON for confirmada, ou seja quando as informações da tabela fonte existirem  na tabela de destino. Você pode utilizar até duas cláusulas sendo que uma terá um UPDATE e outra uma operação de DELETE.

[WHEN NOT MATCHED [BY TARGET] THEN] = Acontece quando as informações na tabela de destino ou Target não existe,  fazendo assim que a mesma possa ser inserida. Lembrando que essa opção so pode estar presente 1 vez dentro do Merge.

[WHEN NOT MATCHED BY SOURCE THEN] = Pode ser definido por um UPDATE ou DELETE das informações que existem na tabela de destino e não existem na tabela fonte, você pode utilizar até duas cláusulas sendo que uma terá um UPDATE e outra uma operação de DELETE.

Utilizando o MERGE !

Um cenário comun seria mover informações de uma tabela para outra, sendo assim temos uma tabela contendo todos os Clientes já cadastrados em nosso sistema, e uma outra tabela chamada NovosClientes que já está populada com algumas informações, e será usada para um novo sistema, sendo assim vamos atualizar os clientes que já estão nesta tabela e adicionar novos dados.

–*************************************************************

–NovosClientes                                                 

–*************************************************************

CREATE TABLE NovosClientes

(

      ID INT IDENTITY(1,1) NOT NULL,

      Nome VARCHAR(50) NOT NULL,

      EMAIL VARCHAR(100) NULL,

      Telefone VARCHAR(30) NULL

)

GO

 

–Inserção Informações

INSERT INTO NovosClientes(Nome, EMAIL, Telefone)

SELECT FirstName + ‘.’ + LastName AS Nome ,D.EmailAddress AS EMAIL, D.Phone AS Telefone

FROM AdventureWorksLT.SalesLT.Customer AS D

TABLESAMPLE (10 PERCENT)

 

–*************************************************************

–Clientes                                                      

–*************************************************************

CREATE TABLE Clientes

(

      ID INT IDENTITY(1,1) NOT NULL,

      Nome VARCHAR(50) NOT NULL,

      EMAIL VARCHAR(100) NULL,

      Telefone VARCHAR(30) NULL

)

go

 

INSERT INTO Clientes(Nome, EMAIL, Telefone)

SELECT FirstName + ‘.’ + LastName AS Nome ,D.EmailAddress AS EMAIL, D.Phone AS Telefone

FROM AdventureWorks.Person.Contact AS D

TABLESAMPLE (10 PERCENT)

Depois da estrutura criada e populada, agora vamos utilizar o Merge para vizualiar as informações, mas antes disso vamos ver quantos registros cada tabela tem….

image

BEGINTRANSACTION

SELECT@@TRANCOUNT

 

MERGE INTO NovosClientes AS E

USING Clientes AS C

      ON E.Nome = C.Nome

WHEN MATCHED THEN

      UPDATE

            SET E.Telefone = C.Telefone,

                  E.EMAIL = C.EMAIL

WHEN NOT MATCHED THEN

      INSERT (Nome, EMAIL, Telefone)

      VALUES (Nome, EMAIL, Telefone);

     

ROLLBACKTRANSACTION

—    COMMIT TRANSACTION

Se olharmos novamente as tabelas temos que…

image

Claramente aqui que a tabela de novos clientes agora possuem mais registros, ou seja alguns registros foram atualizados pela cláusula ON que foi especificada e outros registros foram inseridos porque não foi satisfeito pela cláusula.

Os registros foram inseridos, mais como sabemos qual foi realizado um UPDATE ou INSERT, bem boa pergunta….então vamos descobrir..

Podemos utilizar a cláusula OUTPUT junto com MERGE.

OUTPUT = Promove a habilidade de acessar os dados que estão sendo inseridos e deletados. Essa função só poderia ser realizada no SQL Server 2005 através de triggers agora a mesma pode ser utilizada no SQL Server 2008 nas operações MERGE, INSERT, UPDATE e DELETE.

Agora para descobrirmos o que foi inserido e o que foi atualizado no nosso caso iremos colocar a opção OUTPUT assim.

BEGINTRANSACTION

SELECT@@TRANCOUNT

 

MERGE INTO NovosClientes AS E

USING Clientes AS C

      ON E.Nome = C.Nome

WHEN MATCHED THEN

      UPDATE

            SET E.Telefone = C.Telefone,

                  E.EMAIL = C.EMAIL

WHEN NOT MATCHED THEN

      INSERT (Nome, EMAIL, Telefone)

      VALUES (Nome, EMAIL, Telefone)

OUTPUT $action, inserted.*, SUSER_NAME() AS NomeUsuario;

 

ROLLBACKTRANSACTION

—    COMMIT TRANSACTION

image

Assim com essa opção conseguimos pegar as informações da ação realizada, e para complementar nossos dados estou pegando o usuário que está realizando essa operação..

image

Assim conseguimos visualizar o que aconteu durante a operação MERGE….

Se desejar gravar essa informações, muito bem podemos fazer tambêm….

Criamos uma tabela na qual receberá as informações e realizamos a operação MERGE, especificando no final a inserção das ações dentro desta tabela.

–*************************************************************

–DadosHistorico                                                      

–*************************************************************

CREATE TABLE DadosHistorico

(

      EstadoInsertUpdate VARCHAR(50),

      ID INT NOT NULL,

      Nome VARCHAR(50) NOT NULL,

      EMAIL VARCHAR(100) NULL,

      Telefone VARCHAR(30) NULL,

      NomeUsuario VARCHAR(30) NULL

)

go

BEGINTRANSACTION

SELECT@@TRANCOUNT

 

MERGE INTO NovosClientes AS E

USING Clientes AS C

      ON E.Nome = C.Nome

WHEN MATCHED THEN

      UPDATE

            SET E.Telefone = C.Telefone,

                  E.EMAIL = C.EMAIL

WHEN NOT MATCHED THEN

      INSERT (Nome, EMAIL, Telefone)

      VALUES (Nome, EMAIL, Telefone)

OUTPUT $action, inserted.*, SUSER_NAME() INTO DadosHistorico;

image

Ou seja os dados foram inseridos nesta tabela, podendo agora você ter controle das informações que foram realizadas.

Gostou do post, deixe seu comentário…..