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.