domingo, 20 de enero de 2008

Sentencia MERGE

Dios y su ordenador de SQL y PLSQLSQL y PL/SQL - La nueva sentencia MERGE

La sentencia MERGE, a la que muchos denominan UPSERT debido a su funcionalidad, está disponible desde la aparición de la versión 9i de la base de datos Oracle. Se trata de una de las funcionalidades del kerneltecnología ETLExtract, Transform and Load - Extraer, Transformar y Cargar) con las bases de datos Oracle. Este tipo de tecnología puede utilizarse y está especialmente enfocada para ser usada en aplicaciones de data warehousing (almacen de datos). Básicamente, lo que permite la sentencia SQL MERGE es, dependiendo de una condición lógica, actualizar registros (UPDATE) cuando la condición se cumple, o insertar registros (INSERT) cuando dicha condición no se cumple, de ahí surge la denominación de UPSERT.
de Oracle más utiles a la hora de permitir el uso de la (


Anteriormente a la versión 9i de Oracle, la alternativa en SQL era ejecutar dos sentencias DML, un UPDATE y un INSERT, cada una utilizando condiciones lógicas opuestas. En cuanto a las alternativas en PL/SQL eran: bien intentar insertar un registro y si la sentencia INSERT fallaba debido a una excepcion PLSQL del tipo DUP_VAL_ON_INDEX, entonces realizar un UPDATEUPDATE devolvía SQL%NOTFOUND, entonces ejecutar la correspondiente sentencia INSERT.

Las ventajas de la sentencia SQL MERGE son claras:

- Permite con una misma sentencia realizar un UPDATE si el registro existe, o un INSERT si se trata de un nuevo registro.

- La sentencia puede paralelizarse de forma transparente.

- Se evita la necesidad de realizar actualizaciones múltiples.

- Es especialmente útil para realizar operaciones en masa y, como ya he mencionado, en aplicaciones de data warehousing.

- El rendimiento de la base de datos mejora ya que, al necesitarse menos sentencias SQL para realizar las mismas operaciones, también se necesitan menos accesos a las tablas fuente.

Ejemplo de sentencia MERGE

En el presente ejemplo voy a partir del hecho de que tenemos dos tablas en un data warehouse, una de ellas con muchos registros denominada clientes y otra más pequeña denominada datos_cli cuyos registros deben insertarse en la tabla clientes. En pocas palabras, estoy suponiendo que la tabla datos_cli contiene los cambios a realizar sobre la tabla clientes. La sentencia SQL MERGE que debemos utilizar para actualizar la tabla cliente podría ser la siguiente:

del registro en cuestión; bien intentar actualizar un registro y si la sentencia

MERGE INTO clientes cli USING datos_cli dac
ON (cli.cliente_id = dac.cliente_id)
WHEN MATCHED THEN
UPDATE SET
cli.nombre = dac.nombre,
cli.direccion = dac.direccion
WHEN NOT MATCHED THEN
INSERT (cliente_id, nombre, direccion)
VALUES (dac.cliente_id, dac.nombre, dac.direccion);

Así pues, la sentencia MERGE del ejemplo realizará las siguientes operaciones:

- Si existe un registro en datos_cli con el mismo ID de otro registro en la tabla clientes, entoces actualizará el valor de los campos nombre y dirección de la tabla clientes con los valores correspondientes de la tabla datos_cli.

- Si no existe un registro en clientes con el ID del registro de datos_cli que está siendo procesado, entonces se insertará dicho registro en la tabla clientes.

En resumen, la sintaxis de la sentencia MERGE debe incorporar:

Una
cláusula INTO, que especifica la tabla destino donde los registros serán actualizados o insertados.

Una
cláusula USING, especificando el origen de los datos que van a ser insertados o que van a servir para actualizar la tabla destino. El origen de los datos puede tratarse de una tabla, una vista, o del resultado de la ejecución de una consulta SELECT.

Una
cláusula ON, que especifica la condición bajo la cual se realizará, bien la operación UPDATE (si la condición se cumple), bien la operación INSERT (si la condición no se cumple).

Las
cláusulas WHEN MATCHED | NOT MATCHED, que son las que indican a la base de datos Oracle que acción realizar si se cumple o no se cumple la condición del ON. Estas dos cláusulas se pueden poner en cualquier orden.

10 comentarios:

Skatox dijo...

Gracias por este artículo, explicaste bien el merge.

JJ dijo...

Por cierto, ¿se podria utilizar un merge dentro del bucle de un cursor? y dentro de la parte USING hacer referencia a los valores del cursor??

Gracias por las aclaraciones...

Anónimo dijo...

buena especificacion se agradece sigan asi gracias

Sebastian dijo...

Muy buen post! ¿Se puede hacer merge con varray o nested-tables?

HILMER dijo...

Gracias, buen articulo

Wladimir dijo...

No sabes lo importante que me resulta esto. Muchas gracias

Anónimo dijo...

Buena explicación !!! Thx !

Carlos Soriano dijo...

Excelente artículo, me has salvado la vida al ver desaparecer el /*+bypass_ujvc*/ xD

Anónimo dijo...

Aunque este post ya tiene 6 años.. debo decir que esta muy bien explicado, ¡felicitaciones!

Anónimo dijo...

Excelente! Que buena explicación