domingo, 17 de julio de 2016

Manipulación de Grandes Juegos de Datos

Objetivos:
•Manipular datos mediante subconsultas.
•Describir las funciones de las inserciones de varias tablas.
•Utilizar los siguientes tipos de inserciones de varias tablas.
INSERT incondicional.
INSERT de pivoting.
ALL INSERT condicional.
FIRST INSERT condicional.
•Fusionar filas en una tabla.

NOTA: Usamos como ejemplo la base de datos: ORCL, la cual viene por defecto en cualquier versión de ORACLE.
_____________________________________________________________________________________
Uso de Subconsultas para Manipular Datos.
Las subconsultas se pueden utilizar para recuperar datos de una tabla que podrá utilizar como entrada en una inserción (INSERT) en una tabla diferente. Así, le resultará fácil copiar grandes volúmenes de datos de una tabla a otra con una sola sentencia SELECT. De forma parecida, puede utilizar subconsultas para realizar actualizaciones y supresiones masivas en la cláusula WHERE de las sentencias UPDATE y DELETE. También puede utilizar subconsultas en la cláusula FROM de una sentencia SELECT. Esto se conoce como vista en línea.

Puede utilizar subconsultas en sentencias DML para:
•Copiar datos de una tabla a otra.
•Recuperar datos de una vista en línea.
•Actualizar datos en una tabla basándose en los valores de otra tabla.
•Suprimir filas de una tabla basándose en filas de otra tabla.

Copia de Filas de Otra Tabla.
Puede utilizar sentencias INSERT para agregar filas a una tabla en la que los valores se deriven de tablas existentes. En lugar de la cláusula VALUES, utilice una subconsulta.

Sintaxis:
INSERT INTO table [ column (, column) ]
    subquery;

En la sintaxis:
table es el nombre de la tabla a la cual se va a insertar.
column es el nombre de la columna de la tabla que se va a rellenar.
subquery es la subconsulta que devuelve filas a la tabla.

El número de columnas y los tipos de datos de la lista de columnas de la cláusula INSERT se deben corresponder con el número de valores y los tipos de datos de la subconsulta. Para crear una copia de las filas de una tabla, utilice SELECT * en la subconsulta.

Ejemplo:
CREATE TABLE agentes_ventas
(
  agente_id NUMBER(6),
  agent_name VARCHAR2(45),
  puesto VARCHAR2(20),
  salario NUMBER(8,2),
  comision NUMBER(2,2)
);
/*Creamos la tabla: agentes_ventas para insertar los empleados con puestos de ventas.*/
---
INSERT INTO agentes_ventas(agente_id, agent_name, salario, comision)
  SELECT employee_id, first_name||' '||last_name, salary, commission_pct
  FROM   employees
  WHERE  job_id LIKE '%REP%';
/*Aquí insertamos en la tabla agentes_ventas todos los empleados con un puesto de trabajo que contenga la cadena REP.*/
---
Inserción mediante una Subconsulta como Destino.
Puede utilizar una subconsulta en lugar del nombre de tabla en la cláusula INTO de la sentencia INSERT

La lista de selección de esta subconsulta debe tener el mismo número de columnas que la lista de columnas de la cláusula VALUES. Para que la sentencia INSERT funcione correctamente, se deben seguir las reglas de las columnas de la tabla base. Por ejemplo, no se puede agregar un identificador de empleado duplicado ni omitir un valor para una columna obligatoria NOT NULL

Esta aplicación de las subconsultas evita tener que crear una vista únicamente para realizar una inserción (INSERT).

Ejemplo:
INSERT INTO
        (SELECT agente_id, agent_name,
                         salario, comision
         FROM   agentes_ventas) 
VALUES(99999, 'Julio Voltio',
                8200, 0.30);
/*Acá vemos como usar una subconsulta en la cláusula INSERT INTO de lugar de la cláusula VALUES.*/
---
Recuperación de Datos con una Subconsulta como Origen.
Puede utilizar una subconsulta en la cláusula FROM de una sentencia SELECT, lo cual es muy parecido al uso de las vistas. Una subconsulta en la cláusula FROM de una sentencia SELECT se denomina también vista en línea. Una subconsulta en la cláusula FROM de una sentencia SELECT define un origen de datos para una sentencia SELECT en particular y sólo para esa sentencia SELECT

Ejemplo:
SELECT  a.last_name, a.salary, 
                 a.department_id, b.salavg
FROM     employees a, (SELECT department_id, 
                                        AVG(salary) salavg
                                        FROM     employees
                                        GROUP BY department_id) b
WHERE  a.department_id = b.department_id
AND       a.salary > b.salavg;
/*El ejemplo muestra los apellidos, salarios, números de departamento y los salarios medios de todos los empleados que ganan más que el salario medio en su departamento. La subconsulta de la cláusula FROM se denomina b y la consulta externa hace referencia a la columna SALAVG con este alias.*/
---
Actualización de Columnas con Subconsultas.
Para actualizar varias columnas en la cláusula SET de una sentencia UPDATE, puede escribir varias subconsultas. 

Sintaxis:
UPDATE table
SET     column  =
             (SELECT  column
              FROM table
              WHERE condition)
       [ ,
        column  =
             (SELECT  column
              FROM table
              WHERE condition)]
[WHERE  condition ];

Ejemplo:
UPDATE   agentes_ventas
SET      puesto  = (SELECT  job_id 
                    FROM    employees 
                    WHERE   employee_id = 205), 
         salario  = (SELECT   salary 
                    FROM    employees 
                    WHERE   employee_id = 205
WHERE    agente_id  BETWEEN 150 AND 170;
/*En este ejemplo se actualiza la tabla agentes_ventas basándose en los valores de la tabla employees. Cambia el puesto y el salario de los empleados con IDs entre 150 y 170 para hacerlos corresponder con los del empleado 205.*/
---
Supresión de Filas Basándose en Otra Tabla.
Puede utilizar subconsultas para suprimir filas de una tabla basándose en valores de otra tabla. 

Ejemplo:
DELETE FROM employees
WHERE employee_id NOT IN
                     (SELECT manager_id
                      FROM employees
                      WHERE  manager_id IS NOT NULL)
AND   department_id =
                     (SELECT department_id
                      FROM departments
                      WHERE  department_name = 'IT');
/*En el ejemplo se suprimen todos los empleados que no son supervisores y que están en el departamento “IT”. La subconsulta busca en la tabla DEPARTMENTS el número de departamento basándose en el nombre de departamento “IT”. La segunda subconsulta proporciona el número de departamento a la consulta principal, que suprime filas de datos de la tabla EMPLOYEES basándose en este número de departamento.*/
---
Palabras Clave WITH CHECK OPTION.
Especifique WITH CHECK OPTION para indicar que, si se utiliza la subconsulta en lugar de una tabla en una sentencia INSERTUPDATE DELETE, en esa tabla no se permiten cambios que produzcan filas que no estén incluidas en la subconsulta. 

Ejemplo:
INSERT INTO  (SELECT employee_id, last_name, email,
                     hire_date, job_id, salary
              FROM   employees 
              WHERE  department_id = 50 
              WITH CHECK OPTION)
VALUES (99998, 'Smith', 'JSMITH',
        TO_DATE('07-JUN-99', 'DD-MON-RR'), 
        'ST_CLERK', 5000);
/*En el ejemplo, se utilizan las palabras clave WITH CHECK OPTION. La subconsulta identifica filas que están en el departamento 50, pero el identificador de departamento no está en la lista SELECT y no se proporciona un valor para dicho identificador en la lista VALUES. La inserción de esta fila da como resultado un identificador de departamento nulo, que no está en la subconsulta, por esta razón no se inserta el registro. Si eliminamos la .cláusula WHERE, la inserción se realiza.*/
_____________________________________________________________________________________
Valores por Defecto Explícitos.
La palabra clave DEFAULT se puede utilizar en sentencias INSERT y UPDATE para identificar un valor de columna por defecto. Si no existe ningún valor por defecto, se utiliza un valor nulo.

La opción DEFAULT le ahorra tener que codificar el valor por defecto en los programas o consultar el diccionario para encontrarlo, que es lo que se debía hacer antes de que se introdujese esta función. Es problemático codificar el valor por defecto si éste cambia, porque también habría que cambiar el código de forma consecuente. No se suele acceder al diccionario en un programa de aplicación, por lo que esta función es muy importante.

•La función de valor por defecto explícito le permite utilizar la palabra clave DEFAULT como valor de columna donde se desea el valor por defecto de columna.
•Esta función se ha agregado por compatibilidad con el estándar SQL:1999.
•Esto permite al usuario controlar dónde y cuándo se debe aplicar el valor por defecto a los datos.

Nota: Al crear o modificar una tabla, puede especificar un valor por defecto para una columna. La palabra clave DEFAULT no puede ser usado en la cláusula WHERE.

Ejemplos:
ALTER TABLE agentes_ventas
ADD 
(
    departamento NUMBER(4) DEFAULT 80
);
/*Agregamos la columna departamento a la tabla agentes_ventas con 80 como valor por defecto. Al ejecutar esta sentencia, todos los registros ya insertados en la tabla toman el valor 80.*/
---
INSERT INTO agentes_ventas(agente_id, agent_name, departamento)
VALUES (555, 'Vicente Lopez'50);
/*Acá insertamos un registro con el # de departamento 50. Tener en cuenta que pudimos usar la función DEFAULT en lugar de 50 para así insertar el numero 80, de igual manera si omitíamos esa columna,  hubiese tomado el valor por defecto. */
---
UPDATE agentes_ventas
SET departamento = DEFAULT
WHERE departamento = 50;
/*En este ejemplo le cambiamos el # de departamento a los empleados(en este caso 1) con # de departamento 50 al valor por defecto(80).*/
_____________________________________________________________________________________
Sentencias INSERT de Varias Tablas.
En una sentencia INSERT de varias tablas, se insertan filas calculadas derivadas de las filas devueltas de la evaluación de una subconsulta en una o más tablas.

Las sentencias INSERT de varias tablas pueden desempeñar un papel muy útil en el supuesto de un almacén de datos. Debe cargar el almacén de datos con regularidad para que pueda cumplir su propósito de facilitar el análisis de negocio. Para ello, se deben extraer y copiar datos de uno o más sistemas operativos al almacén de datos. El proceso de extracción de datos del sistema de origen y su transferencia al almacén de datos se suele denominar ETL (siglas de extraction, transformation, and loading, o extracción, transformación y carga).

Durante la extracción, se deben identificar y extraer los datos deseados de diferentes orígenes como, por ejemplo, aplicaciones y sistemas de Bases de Datos. Después de la extracción, los datos se deben transportar físicamente al sistema de destino o a un sistema intermedio para continuar su procesamiento. Dependiendo del medio de transporte seleccionado, algunas transformaciones se pueden realizar durante este proceso. Por ejemplo, una sentencia SQL que acceda directamente a un destino remoto a través de un gateway puede concatenar dos columnas como parte de la sentencia SELECT.

Una vez cargados los datos en la Base de Datos Oracle, las transformaciones de datos se pueden ejecutar mediante operaciones SQL. Una sentencia INSERT de varias tablas es una de las técnicas para implementar transformaciones de datos SQL.

Las sentencias INSERT de varias tablas ofrecen las ventajas de la sentencia INSERT ... SELECT cuando hay varias tablas implicadas como destinos. Con la funcionalidad anterior a la Base de Datos Oracle9i, era necesario tratar con n sentencias INSERT ... SELECT independientes, procesando los mismos datos de origen n veces y aumentando la carga de trabajo de transformación n veces. 

Como sucede con la sentencia INSERT ... SELECT existente, la nueva sentencia se puede paralelizar y utilizar con el mecanismo de carga directa para obtener un rendimiento más optimo. 

Cada registro de cualquier flujo de entrada como, por ejemplo, una tabla de Base de Datos no relacional, se puede convertir ahora en varios registros para un entorno de tabla de Base de Datos más relacional. Para implementar esta funcionalidad de forma alternativa, había que escribir varias sentencias INSERT.

•La sentencia INSERT SELECT se puede utilizar para insertar filas en varias tablas como parte de una única sentencia DML
•Las sentencias INSERT de varias tablas se pueden utilizar en sistemas de almacenes de datos para transferir datos de uno o más orígenes operativos a un juego de tablas destino. 
•Proporcionan una mejora significativa del rendimiento en: 
DML único frente a varias sentencias INSERT SELECT 
DML único frente a un procedimiento para realizar varias inserciones mediante la sintaxis IF...THEN.

Tipos de Sentencias INSERT de Varias Tablas.
Los tipos de sentencias INSERT de varias tablas son:
INSERT incondicional.
ALL INSERT condicional.
FIRST INSERT condicional.
INSERT de pivoting.

Se utilizan diferentes cláusulas para indicar el tipo de inserción (INSERT) que se ejecutará.

Sintaxis:
Incondicional_insert_clause:
INSERT [ALL] [unconditional_insert_clause]
[insert_into_clause values_clause] (subquery)


•Conditional_insert_clause:
INSERT [ALL] [FIRST]
[WHEN condition THEN] [insert_into_clause values_clause]
[ELSE] [insert_into_clause values_clause]


INSERT Incondicional: ALL into_clause
Especifique ALL seguido de varias cláusulas insert_into_clauses para realizar una inserción incondicional de varias tablas. Oracle Server ejecuta cada insert_into_clause una vez para cada fila devuelta por la subconsulta.

INSERT Condicional: conditional_insert_clause
Especifique la cláusula conditional_insert_clause para realizar una inserción (INSERT) condicional de varias tablas. Oracle Server filtra cada cláusula insert_into_clause a través de la condición WHEN correspondiente, lo que determina si se ejecutará insert_into_clause. Una única sentencia INSERT de varias tablas puede contener hasta 127 cláusulas WHEN.

INSERT Condicional: ALL
Si especifica ALL, Oracle Server evalúa cada cláusula WHEN independientemente de los resultados de la evaluación de cualquier otra cláusula WHEN. Para cada cláusula WHEN cuya condición se evalúe como verdadera, Oracle Server ejecuta la lista correspondiente de cláusulas INTO.

INSERT Condicional: FIRST
Si especifica FIRST, Oracle Server evalúa cada cláusula WHEN en el orden en que aparece en la sentencia. Si la primera cláusula WHEN se evalúa como verdadera, Oracle Server ejecuta la cláusula INTO correspondiente y salta las cláusulas WHEN siguientes para la fila especificada.

INSERT Condicional: Cláusula ELSE
Para una fila especificada, si no se evalúa ninguna cláusula WHEN como verdadera:
•Si ha especificado una cláusula ELSE, Oracle Server ejecuta la lista de cláusulas INTO asociadas a la cláusula ELSE.
•Si no ha especificado una cláusula ELSE, Oracle Server no realiza ninguna acción para esa fila.

Restricciones en Sentencias INSERT de Varias Tablas
•Se pueden realizar sentencias INSERT de varias tablas sólo en tablas, no en vistas ni en vistas materializadas.
•No se puede realizar una inserción (INSERT) de varias tablas en una tabla remota.
•No se puede especificar una expresión de recopilación de tablas al realizar una inserción (INSERT) de varias tablas.
•En una inserción (INSERT) de varias tablas, no se pueden combinar todas las cláusulas insert_into_clauses para especificar más de 999 columnas de destino.

INSERT de Pivoting.

El pivoting es una operación en la que se debe crear una transformación tal que cada registro de cualquier flujo de entrada como, por ejemplo, una tabla de base de datos no relacional, se debe convertir en varios registros para un entorno de tablas de base de datos más relacional.

Ejemplos:
CREATE TABLE emp_by_dept
(
  dept_id NUMBER(6),
  nombre VARCHAR2(30),
  cantidad NUMBER(3)
);
---
CREATE TABLE emp_by_mgr
(
  mgr_id NUMBER(6),
  nombre VARCHAR2(45),
  cantidad NUMBER(3)
);
/*En las sentencias anteriores creamos las tablas que usaremos en nuestros ejemplos; emp_by_dept: empleados por departamento y emp_by_mgr: empleados por manager.*/
---
INSERT ALL 
  INTO emp_by_dept VALUES(dept_id,nombre_dept,cant_dept) 
  INTO emp_by_mgr VALUES(mgr_id,nombre_mgr,cant_mgr)
      SELECT 
            NULL AS dept_id,
            NULL AS nombre_dept,
            NULL AS cant_dept,
            m.employee_id AS mgr_id, 
            m.first_name||' '||m.last_name AS nombre_mgr, 
            count(e.employee_id) AS cant_mgr
      FROM employees m, employees e
      WHERE m.employee_id = e.manager_id
      GROUP BY m.employee_id, m.first_name||' '||m.last_name
      UNION
      SELECT 
          d.department_id AS dept_id, 
          d.department_name AS nombre_dept, 
          count(e.employee_id) AS cant_dept,
          NULL AS mgr_id,
          NULL AS nombre_mgr,
          NULL AS cant_mgr
      FROM employees e, departments d
      WHERE e.department_id = d.department_id
      GROUP BY d.department_id, d.department_name;
/*En el ejemplo anterior vemos el uso de la sentencia INSERT ALL unconditional , en la cual insertados todos los registros de la consulta, en las tablas creadas anteriormente; El primer Query(antes del UNION) retorna 3 columnas con valores nulos(para así hacerla corresponder con la consulta debajo del UNION) y la cantidad de empleados de la tabla employees ordenados por nombre y numero de manager; El segundo Query retorna la cantidad de empleados ordenados por nombre y numero de departamento mas nuestras columnas ficticias. Ya que dicha Sentencia inserta cada registro una vez por cada tabla, si consultamos nuestras tablas notamos que hay valores nulos en algunos registros(producto de nuestras columnas ficticias: NULL).*/
---
INSERT ALL 
WHEN dept_id IS NULL
AND nombre_dept IS NULL THEN
  INTO emp_by_mgr VALUES(mgr_id,nombre_mgr,cant_mgr)
WHEN dept_id IS NOT NULL
AND nombre_dept IS NOT NULL THEN  
  INTO emp_by_dept VALUES(dept_id,nombre_dept,cant_dept)
      SELECT 
            NULL AS dept_id,
            NULL AS nombre_dept,
            NULL AS cant_dept,
            m.employee_id AS mgr_id, 
            m.first_name||' '||m.last_name AS nombre_mgr, 
            count(e.employee_id) AS cant_mgr
      FROM employees m, employees e
      WHERE m.employee_id = e.manager_id
      GROUP BY m.employee_id, m.first_name||' '||m.last_name
      UNION
      SELECT 
          d.department_id AS dept_id, 
          d.department_name AS nombre_dept, 
          count(e.employee_id) AS cant_dept,
          NULL AS mgr_id,
          NULL AS nombre_mgr,
          NULL AS cant_mgr
      FROM employees e, departments d
      WHERE e.department_id = d.department_id
      GROUP BY d.department_id, d.department_name;

/*En este ejemplo usamos la misma consulta del ejemplo anterior, pero ahora mostrando el uso de la sentencia INSERT ALL conditional; Los registros en los cuales el campo dept_id IS NULL y nombre_dept IS NULL(Query antes del UNION) son insertados en emp_by_mgr; los registros en los cuales el campo dept_id IS NOT NULL y nombre_dept IS NOT NULL(Query después del UNION) son insertados en la tabla emp_by_dept.
Nota: si algún registro cumple con las dos condiciones, es insertado en ambas tablas(no aplica para nuestro ejemplo).*/
CREATE TABLE excelente_sal
(
  numero_dept NUMBER(4),
  cant_emp NUMBER(3),
  total_sal NUMBER(7)
);
---
CREATE TABLE buen_sal
AS
  SELECT *
  FROM excelente_sal;
---
CREATE TABLE mal_sal
AS
  SELECT *
  FROM excelente_sal;
---
CREATE TABLE pesimo_sal
AS
  SELECT *
  FROM excelente_sal;
/*Las Tablas anteriores serán usadas para nuestro ejemplo.*/
INSERT FIRST
WHEN sal/cantidad  > 9999 THEN
  INTO excelente_sal VALUES(dept_id, cantidad, sal)
WHEN sal/cantidad  > 8000 THEN
  INTO buen_sal VALUES(dept_id, cantidad, sal)
WHEN sal/cantidad  > 4000 THEN
  INTO mal_sal VALUES(dept_id, cantidad, sal)
ELSE
  INTO pesimo_sal VALUES(dept_id, cantidad, sal)
    SELECT
        department_id AS dept_id,
        COUNT(employee_id) AS cantidad,
        SUM(salary) AS sal  
    FROM employees
    GROUP BY department_id;
/*En el INSERT FIRST cada registro se inserta una vez dependiente de la condición que satisfaga, Aunque un registro cumpla con mas de un condición solo se inserta una vez(en la primera condición WHEN THEN).*/
---
Para el ejemplo de la sentencia pivoting suponga:
•Que recibe un juego de registros de ventas, de una tabla de Base de Datos no relacional, FUENTE_DATOS_VENTAS, con el siguiente formato: 
- id_emp, id_semana, ventas_lun, ventas_mar, ventas_mi, ventas_ju, ventas_vi
•Desea almacenar estos registros en la tabla INFO_VENTAS con un formato relacional más normal: 
id_emp, semana, ventas
•Mediante una sentencia INSERT de pivoting, convierta el juego de registros de ventas de la tabla de la Base de Datos no relacional al formato relacional.

INSERT ALL
  INTO info_ventas VALUES (id_emp,id_semana,ventas_lun)
  INTO info_ventas VALUES (id_emp,id_semana,ventas_mar)
  INTO info_ventas VALUES (id_emp,id_semana,ventas_mi)
  INTO info_ventas VALUES (id_emp,id_semana,ventas_ju)
  INTO info_ventas VALUES (id_emp,id_semana,ventas_vi)
SELECT
      id_emp,
      id_semana,
      ventas_lun,
      ventas_mar,
      ventas_mi,
      ventas_ju,
      ventas_vi
FROM fuente_datos_ventas;
/*En este ejemplo, cada registro extraído de la tabla fuente_datos_ventas es insertado 5 veces en la tabla info_ventas, pero ahora con un formato/distribución diferente.*/
_____________________________________________________________________________________
Sentencias MERGE.
Oracle Server soporta la sentencia MERGE para operaciones INSERT, UPDATE y DELETE. Mediante esta sentencia, puede actualizar, insertar o suprimir una fila condicionalmente en una tabla, con lo que se evitan varias sentencias DML. La decisión de actualizar, insertar o suprimir en la tabla destino se basa en una condición de la cláusula ON

Hay que tener privilegios de objeto INSERT UPDATE en la tabla destino y el privilegio de objeto SELECT en la tabla origen. Para especificar la cláusula DELETE de la cláusula merge_update_clause, también debe tener el privilegio de objeto DELETE en la tabla destino. 

La sentencia MERGE es determinista. No se puede actualizar varias veces la misma fila de la tabla destino en la misma sentencia MERGE

Un enfoque alternativo es utilizar bucles PL/SQL y varias sentencias DML. La sentencia MERGE, sin embargo, es fácil de utilizar y se expresa de forma más sencilla como una única sentencia SQL

La sentencia MERGE es adecuada en diferentes aplicaciones de almacén de datos. Por ejemplo, en una aplicación de almacén de datos, es posible que necesite trabajar con datos procedentes de varios orígenes, algunos de los cuales pueden estar duplicados. Con la sentencia MERGE, puede agregar o modificar filas condicionalmente.

En conclusion la sentencia MERGE:
•Permite actualizar o insertar datos condicionalmente en una tabla de base de datos.
•Realiza una actualización (UPDATE) si existe la fila y una inserción (INSERT) si es una fila nueva: 
–Evita actualizaciones separadas.
–Aumenta el rendimiento y la facilidad de uso.
–Es útil en aplicaciones de almacenes de datos.

Sintaxis:
MERGE INTO table_name table_alias
USING (table|view|sub_query) alias
ON (join condition)
WHEN MATCHED THEN
UPDATE SET

col1 = col_val1,
col2 = col2_val
WHEN NOT MATCHED THEN
INSERT
(column_list)
VALUES (column_values);


En la sintaxis:
•Cláusula INTO especifica la tabla destino que se va a actualizar o en la que se va a insertar.
•Cláusula USING identifica el origen de los datos que se van a actualizar o insertar; puede ser una tabla, una vista o una subconsulta.
•Cláusula ON condición según la cual la operación MERGE actualiza o inserta.
•WHEN MATCHED |WHEN NOT MATCHED  indica al servidor cómo responder a los resultados de la condición de unión.

Ejemplo:
CREATE TABLE nivel_emp
AS
  SELECT 
        employee_id AS id_emp,
        first_name||' '||last_name AS nombre, 
        DECODE (ROWNUM,
                      1, 30,
                      235,
                      340,
                      50AS edad,
        department_id AS id_dept,
        salary AS salario,
        'Elite' AS nivel
  FROM employees
  WHERE salary > 12000;
/*Para los futuros ejemplos creamos la tabla nivel_emp; con los campos id_emp, nombre, edad, id_dept, salario y nivel; Al momento de su creación la tabla contendrá algunos registros que cumplen con la condición de salary > 12000; La columna edad de nuestra tabla fue poblada con el DECODE, si el numero de fila retornado en la consulta era 1 inserta 30, si es 2 -> 35, 3 -> 40 y si es mas de ahí sera 50; la columna nivel tendrá 'Elite' para cada registro insertado.*/
---
MERGE INTO nivel_emp n
  USING employees e
  ON (n.id_emp = e.employee_id)
WHEN MATCHED THEN
  UPDATE SET
     n.edad = 31,
     n.id_dept  = 0,
     n.salario = 30000
WHEN NOT MATCHED THEN
 INSERT VALUES(e.employee_id, e.first_name||' '||e.last_name,
          25, 3, e.salary, 'Peon');
/*Acá vemos el uso de la sentencia MERGE, en la cual se actualizan los campos edad, id_dept y salario de la tabla nivel_emp para los id_emp que existan en la tabla employees; los registros que no existan en nivel_emp son insertados.*/
_____________________________________________________________________________________
_____________________________________________________________________________________
Fuente: Base de Datos Oracle 10g: Conceptos Fundamentales de SQL 1