Oracle – Merge

MESCLANDO LINHAS COM MERGE

O Oracle Database 9i introduziu a instrução MERGE, que permite mesclar linhas de uma tabela em
outra. Por exemplo, talvez você queira mesclar alterações dos produtos listados em uma tabela na
tabela products.

CREATE TABLE product_changes (
product_id INTEGER
CONSTRAINT prod_changes_pk PRIMARY KEY,
product_type_id INTEGER
CONSTRAINT prod_changes_fk_product_types
REFERENCES product_types(product_type_id),
name VARCHAR2(30) NOT NULL,
description VARCHAR2(50),
price NUMBER(5, 2) );

A consulta a seguir recupera as colunas product_id, product_type_id, name e price dessa
tabela:

 SELECT product_id, product_type_id, name, price
 FROM product_changes;
 PRODUCT_ID PRODUCT_TYPE_ID NAME PRICE
 ---------- --------------- ------------------------------ ----------
 1 1 Modern Science 40
 2 1 New Chemistry  35
 3 1 Supernova      25.99
 13 2 Lunar Landing 15.99
 14 2 Submarine     15.99
 15 2 Airplane      15.99

Digamos que você queira mesclar as linhas da tabela product_changes na tabela products,
como segue:

? Para as linhas com valores de product_id correspondentes nas duas tabelas, atualize as
linhas existentes em products com os valores de coluna de product_changes. Por exemplo,
o produto nº 1 tem um preço em product_changes diferente do que existe em products;
portanto, o preço do produto nº 1 deve ser atualizado na tabela products. Da mesma
forma, o produto nº 2 tem nome e preço diferentes; portanto, os dois valores precisam
ser atualizados em products. Por fim, o produto nº 3 tem um valor de product_type_id
diferente e, portanto, esse valor deve ser atualizado em products.

? Para as linhas novas em product_changes, insira essas novas linhas na tabela products.
Os produtos nº 13, 14 e 15 são novos em product_changes e, portanto, devem ser inseridos
em products.
É mais fácil aprender a usar a instrução MERGE com um exemplo. O exemplo a seguir realiza
a mesclagem conforme definido anteriormente:

MERGE INTO products p
 USING product_changes pc ON ( p.product_id = pc.product_id )
 WHEN MATCHED THEN
 UPDATE
 SET
   p.product_type_id = pc.product_type_id,
   p.name = pc.name, 
   p.description = pc.description,
   p.price = pc.price
 WHEN NOT MATCHED THEN
   INSERT ( p.product_id, p.product_type_id, p.name, p.description, p.price ) 
   VALUES ( pc.product_id, pc.product_type_id, pc.name, pc.description, pc.price );

6 rows merged.

Observe os seguintes aspectos sobre a instrução MERGE:

? A cláusula MERGE INTO especifica o nome da tabela na qual as linhas serão mescladas. No
exemplo, essa tabela é products, que recebeu o apelido p.
? A cláusula USING… ON especifica uma junção de tabela. No exemplo, a junção é feita
nas colunas product_id das tabelas products e product_changes. A tabela product_
changes também recebeu um apelido, pc.
? A cláusula WHEN MATCHED THEN especifica a ação a ser executada quando a cláusula
USING… ON é satisfeita por uma linha. No exemplo, essa ação é uma instrução UPDATE
que configura as colunas product_type_id, name, description e price da linha existente
na tabela products com os valores de coluna da linha correspondente na tabela
product_ changes.
? A cláusula WHEN NOT MATCHED THEN especifica a ação a ser executada quando a cláusula
USING… ON não é satisfeita para uma linha. No exemplo, essa ação é uma instrução INSERT
que adiciona uma linha na tabela products, pegando os valores de coluna da linha
na tabela product_changes.
Se você executar a instrução MERGE anterior, verá que ela relata que seis linhas são mescladas;
essas são as linhas com valores de product_id 1, 2, 3, 13, 14 e 15. A consulta a seguir recupera
as seis linhas mescladas da tabela products:

SELECT product_id, product_type_id, name, price
 FROM products
 WHERE product_id IN (1, 2, 3, 13, 14, 15);
 PRODUCT_ID PRODUCT_TYPE_ID NAME PRICE
 ---------- --------------- ------------------------------ ----------
 1 1 Modern Science 40
 2 1 New Chemistry  35
 3 1 Supernova      25.99
 13 2 Lunar Landing 15.99
 14 2 Submarine     15.99
 15 2 Airplane      15.99

As seguintes alterações foram feitas nessas linhas:
? O produto nº 1 tem um novo preço
? O produto nº 2 tem um novo nome e um novo preço
? O produto nº 3 tem uma nova identificação de tipo de produto
? Os produtos nº 13, 14 e 15 são novos

Referências:  Oracle Database 11g SQL