PL/SQL y ejecuciones en host.
Existe una forma de dar un rodeo a este escenario.
Oracle permite la llamada a procedimientos externos mediante un servicio extproc que debe configurarse en el fichero de alias de servicios «tnsnames.ora» para el cliente, y en el de configuración del listener «listener.ora» en el lado del servidor.
Los ficheros tendrán este aspecto.
Nota: puede haber cambios por la versión del servidor. El ejemplo se implementó sobre Oracle 8.1.7.
Fichero LISTENER.ORA
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC))
)
)
)
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = extproc_agent)
(ORACLE_HOME = E:oracleora92)
(PROGRAM = extproc)
(ENVS = «EXTPROC_DLLS=ANY»)
)
)
Fichero TNSNAMES.ORA
EXTPROC_CONNECTION_DATA =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = IPC)(Key = EXTPROC))
)
(CONNECT_DATA =
(SID = extproc_agent)
)
)
Pasos:
1.- Descarga de un compilador de C++. Este ejemplo utiliza C++Compiler de Borland.
2.- Creación de un programa en C que ejecuta en S.O. un comando dado.
3.- Compilación del programa e implementación de las librerías.
4.- Desde Oracle, creación del objeto LIBRARY (biblioteca).
5.- Creación de un procedimiento PL/SQL que invoque a una función de esa biblioteca.
Creación del programa shell.c
—————————–
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
void __declspec(dllexport) sh(char *);
void sh(char *cmd)
{
system(cmd);
}
Compilación del código C y creación de las librerías .lib y .dll
—————————————————————–
bcc32 -WD shell.c
implib shell.lib shell.dll
Creación del objeto LIBRARY, en la consola de SQL.
————————————————–
SQL> create library shell_lib is ‘C:BorlandBCC55shell.dll’;
2 /
Biblioteca creada.
De modo que ya es posible crear un procedimiento PL/SQL que referencie externamente a esa librería. Ésta se encargará de ejecutar en host el parámetro que le incluyamos. Por ejemplo, un «copy».
————————————————————————————————–
SQL> create or replace procedure shell (
2 cmd IN varchar2)
3 as external
4 library shell_lib
5 name «_sh»
6 language C
7 parameters (cmd string);
8 /
Procedimiento creado.
SQL>
El testeo podrá hacerse con un simple ‘exec’ desde SQL*Plus, ya que equivale a «BEGIN shell(‘parametro’); END;»
—————————————————————————————————————
SQL> exec shell(‘copy c:test*.* c:destino’);
Procedimiento PL/SQL terminado correctamente.
Funciona.