Ejecutar un Stored Procedure de Oracle desde Data Factory
Tags: oracle, storedprocedure, datafactory, pipeline
Published: 2021-01-08 00:59:34

En el momento de la publicación de este tutorial, Data Factory no tiene un conector que permita ejecutar un stored procedure en una base de datos oracle. En este tutorial mostraremos cómo a través de una actividad lookup de un pipeline de Data Factory lograremos ejecutar un Stored Procedure o instrucciones DML en Oracle.

#Prerrequisitos
* [Crear un recurso de Data Factory] (https://docs.microsoft.com/es-es/azure/data-factory/quickstart-create-data-factory-portal#create-a-data-factory) en el [Portal de Azure] (portal.azure.com)

#Pasos
**1. Crear una actividad [Lookup] (https://docs.microsoft.com/en-us/azure/data-factory/control-flow-lookup-activity).**
De acuerdo con la documentación oficial una actividad Lookup nos permite recuperar un dataset de cualquiera de los orígenes de datos compatibles con Azure Data Factory. 
Como podemos observar la actividad está diseñada para consultar una tabla o la ejecución de una sentencia SELECT de oracle.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/1x9a0fangrfz8lm05m8u.PNG)
En Query podemos especificar cualquier instrucción SQL, sin embargo, si la sentencia no es un SELECT válido, Data Factory intentará ejecutar las instrucciones en la base de datos Oracle pero al no recibir el resultado de una consulta, generará un error así haya ejecutado correctamente las instrucciones del query en el servidor de la base de datos.
**2. Crear una sentencia SELECT sobre la tabla [DUAL] (https://docs.oracle.com/cd/B19306_01/server.102/b14200/queries009.htm#:~:text=DUAL%20is%20a%20table%20automatically,row%20with%20a%20value%20X%20.)**
Debido a que los Stored Procedures no se pueden ejecutar dentro de una sentencia SELECT. Debemos crear una función en Oracle que se encargue de ejecutar el procedimiento. 
**2.1 Ejecución de una función Oracle desde el query de una actividad de Lookup.**
Antes de ejecutar el procedimiento almacenado, revisemos el proceso de ejecutar una función en oracle desde Data Factory empleando la tabla DUAL.
Para esto, hemos creado una función en Oracle que cuenta el número de registros de la tabla EMPLEADOS.
```SQL
--Tabla
CREATE TABLE empleados(
   emp_id NUMBER(9),
   nombre VARCHAR2(100),
   CONSTRAINT empleados_pk PRIMARY KEY(emp_id),
);
--Función
create or replace function func_contar_empleados
return integer 
is
   n integer:= 0;
begin
  for r in (select emp_id from empleados) loop
        n := n + 1;
  end loop;
  return n;
end;

```
En Data Factory configuramos el query agregando la siguiente consulta: 
```SQL
SELECT  func_contar_empleados() FROM DUAL;
```
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/jrvpyvsc6fog7ml1zejq.PNG)
Al ejecutar el pipeline podemos verificar que la consulta se ejecutó correctamente. 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/542rkbmca9l69axjqrqj.PNG)
**2.2 Ejecución de Stored Procedure a través de una Función Oracle.** 
Un [Stored Procedure de Oracle] (https://docs.oracle.com/cd/B28359_01/appdev.111/b28843/tdddg_procedures.htm) es un bloque de código PL/SQL que comunmente va a estar asociado a instrucciones DML.
Para ejecutar el Sotred Procedure hemos creado una función en Oracle que recibe los parámetros y en su implementación hace el llamado al Stored Procedure.
```SQL
create or replace procedure insert_empleado (numero in NUMBER, nombre in VARCHAR2) is
 begin
    INSERT INTO empleados (emp_id, nombre)
    Values(numero, nombre);
COMMIT;
end;

create or replace function funcinsert_empleado (numero in NUMBER, nombre in VARCHAR2)
return VARCHAR2 
is
begin
  insert_empleado (numero, nombre);
  return 'done';
end;
```
Siguiendo los pasos de ejecución de una función en Oracle usando la tabla DUAL, tendríamos la siguiente consulta:
```SQL
SELECT  funcinsert_empleado ('1', 'Roger Federer') 
FROM DUAL;
```
Sin embargo, cuando intentamos ejecutar la instrucción obtenemos un error de Oracle que nos notifica que no podemos ejecutar operaciones DML dentro de una instrucción SELECT.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/qhgmozbrg6higmbplvva.PNG)
**2.3 Ejecutar una función Oracle como una transacción Autónoma.**
Debido a que Oracle no permite por defecto la ejecución de instrucciones DML, debemos especificar que la ejecución de la función se realizará como una [TRANSACCIÓN AUTONOMA](https://docs.oracle.com/cd/B14117_01/appdev.101/b10807/13_elems002.htm).
Las Transacciones autónomas van acompañadas de la cláusula AUTONOMOUS_TRANSACTION Pragma. Esta directiva cambia la manera como se ejecutan los subprogramas en una transacción.  

```SQL
create or replace function funcinsert_empleado (numero in NUMBER, nombre in VARCHAR2)
return VARCHAR2 
is
PRAGMA AUTONOMOUS_TRANSACTION;
begin
  insert_empleado (numero, nombre);
  return 'done';
end;
```
La solución aquí planteada permite ejecutar la función que ejecuta el procedimiento almacenado garantizando una transacción autónoma en la ejecución de las instrucciones DML. 
```SQL
SELECT  funcinsert_empleado ('1', 'Roger Federer') 
FROM DUAL;
```
Con estos ajustes, Data Factory ya puede ejecutar la sentencia SELECT.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/y7b3csjufi7wspg1ykfb.PNG)
Tenga en cuenta que, al ejecutar la consulta desde Data Factory, el id del empleado que está pasando como parámetro no se encuentre registrado en la tabla EMPLEADOS, ya que esto generaría un error de primary key. 
#Conclusiones
1. Este tutorial muestra cómo usar la actividad de Lookup de Data Factory para ejecutar un Stored Procedure o instrucciones DML en una base de datos de Oracle. 
2. Si tiene varios Stored Procedures podría definir condicionales dentro de la función que se llama desde la instrucción SELECT y dependiendo de un parámetro, determinar qué Stored Procedure ejecutar.

#¡Gracias por leer!
Si tienes una duda, no dudes en escribir.
[maritzag] [4].
[4]: www.twitter.com/maritzag_123