Muito bom dia a todos!

Hoje vou falar sobre um comando SQL que não vejo muita gente usar mas que é bem poderoso. Esse comando é o MERGE.

Vejo muito código em PL/SQL da seguinte forma:
DECLARE
   var_existe   NUMBER (4) := 0;
BEGIN
   SELECT COUNT (cod)
     INTO var_existe
     FROM tabela
    WHERE cod = :par_cod;

   IF var_existe > 0 THEN
      --Significa que existe valor para o parametro buscado (par_cod)
      UPDATE tabela SET campo = :par_campo WHERE cod = :par_cod;
   ELSE
      --Significa que NÃO existe valor para o parametro buscado
      INSERT INTO tabela  VALUES (:par_cod, :par_campo);     
   END IF;
  
END;

Abstraindo o nome da tabela e seus campos, e levando em consideração à estrutura do bloco de código, basicamente o que é feito é um teste se um determinado valor (:par_cod) existe na tabela, caso exista, será realizada uma alteração (UPDATE) caso contrário será inserido um registro com aquele código (INSERT).

Agora vou falar um pouco sobre o MERGE e depois associar o comando com o bloco PL/SQL acima. 

Segundo Watson, O merge foi introduzido no SQL com o padrão SQL1999, e implementado no Oracle a partir da versão 9i. No Oracle Database 10g o comando foi aprimorado para entrar em conformidade com o padrão SQL2003.

O propósito principal do comando merge é justamente o mesmo do bloco lógico apresentado anteriormente. Uma operação merge não faz nada que não possa ser feito com as instruções INSERT, UPDATE e DELETE – mas com uma passagem pelos dados de origem, ela pode fazer as três coisas. Código alternativo sem MERGE iria exigir três passagem pelos dados, uma para cada comando.

Os dados de Origem para uma instrução MERGE pode ser uma tabela ou uma sub-consulta qualquer. A condição usada para encontrar linhas correspondentes no destino é similar a uma cláusula WHERE. As cláusulas que atualizam, inserem ou excluem linhas são semelhantes aos comandos update, insert e delete. Alguns autores e profissionais  de banco de dados afirmam que o MERGE é o mais complicado dos comandos DML, porém um dos mais poderosos.

A sintaxe do MERGE, em sua forma básica é a informada na Figura 1.
Figura 1 - Estrutura do comando MERGE. (Fonte: Orale Corporation)

Na Figura 1, as operações DML não estão especificadas, então seguem algumas imagens complementares.

Na Figura 2, é apresentada a sintaxe para realizar um UPDATE na linha para o caso de correspondência (MATCHED) na comparação realizada no comando.

Essa mesma estrutura apresentada na Figura 2 pode ser utilizada para a exclusão de linhas na tabela em questão.
Figura 2 - UPDATE/DELETE no MERGE caso a comparação realizada corresponda. (Fonte: Orale Corporation)

Para o caso de não existir uma correspondência na comparação realizada no comando, um INSERT pode ser realizado conforme apresentado na Figura 3.
Figura 3 - INSERT no MERGE caso a comparação realizada não corresponda. (Fonte: Orale Corporation)

Em ambas as situações, Figura 2 e 3, existem um trecho chamado “where_clause, que nada mais é que uma cláusula WHERE normal, no formado: WHERE condição.

Na Figura 1, existe um trecho chamado “error_loggin_clause”, que possui sua sintaxe conforme Figura 4. Sua utilidade é para o caso de erros na execução do comando MERGE. O registro na tabela de log será efetivado caso ocorra algum problema. Para se criar uma tabela para o log do Oracle usa-se o pacote DBMS_ERRLOG.CREATE_ERROR_LOG. Como não é nosso foco principal não abordarei profundamente a questão, mas recomendo a leitura do assunto para um entendimento melhor (é interessante).
Figura 4 - Tratamento de erros no comando MERGE. (Fonte: Oracle Corporation)

Aplicando a sintaxe acima ao nosso bloco lógico citado no início do post temos o seguinte:
MERGE INTO tabela t
     USING (SELECT :par_cod AS cod FROM DUAL) t_aux
        ON (t.cod = t_aux.cod)
WHEN MATCHED THEN
   UPDATE SET campo = :par_campo
WHEN NOT MATCHED THEN
   INSERT     VALUES (:par_cod, :par_campo);

Fiz uma simulação de consulta utilizando a tabela DUAL, apenas para depois testar se o valor “passado por parâmetro” (par_cod) existe na tabela.

A sintaxe está bem simplificada, mas é bastante potente e mais performático em relação ao bloco apresentado anteriormente.

Fica a dica: avaliem se em algum script seu existe uma situação que possa ser utilizado o MERGE e faça um teste. Vale o aprendizado!

Espero conseguido passar o conhecimento!

Grande abraço e até a próxima...

Referências:

Watson, John; Ramklass, Roopesh (2010) – OCA Oracle Database 11g – Fundamentos I SQL – Manual do Exame 1z0-051. Editora: ALTABOOKS.

Oracle Corporation – MERGE. Disponível em http://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_9016.htm. Acessado em 13/03/2013.