Hace unos me surgió la necesidad de realizar el paso de algunos archivos planos entre servidores, el problema es que este paso se va a realizar constantemente, entonces tuve que pensar en una solución que fuera fácil, aparte esos archivos no son mas que información que se procesa e ingresa a una tabla de base de datos.
De entrada la solución que se proponía era realizar un shell script para realizar el paso de archivos vía ftp de un servidor a otro, soluciona el problema pero no estaba muy de acuerdo, primero tener que llamar a un shell para después conectarte a Oracle y llamar a un procedimiento, le quita el control a Oracle sobre el manejo de esos archivos, otra era usar directamente UTL_FILE, pero este paquete sirve para el manejo de archivos en el mismo servidor de base de datos, que yo sepa, con utl_file no se puede manejar archivos de otras maquinas.
Tiempo atrás ya había leído de la existencia de un paquete para el manejo de conexiones tcp, el paquete se llama UTL_TCP, suponía entonces que ya debería de existir algo relacionado con el manejo de archivos entre servidores, la opción lógica era buscar el paquete UTL_FTP pero sorpresa, este no existe, bueno y ¿que dice Google al respecto? le di buscar utl_ftp y me regreso varias paginas, me encontré primero con un script guardado en sourceforce llamado “plsqlftp“, pero no me convenció, su desarrollo se ve casi abandonado y no encontré un solo ejemplo de cómo se usa, acabe descartándolo.
Rascándole un poquito mas a los resultados me tope con el que finalmente implemente, le llamaron “FTP Interfase“, me quedo perfecto para lo que necesitaba, se ve bastante robusto y completo, yo solo use tres funciones, “VERIFY_SERVER”, “PUT” y “GET” pero tiene muchas mas, igual más adelante las pueda necesitar, aquí les dejo el procedimiento que generé para realizar los movimientos de archivos:
--
-- MOVE_FILE
--
-- move file "p_filename" with ftp interfase, use put or get "p_type_move
-- "p_type_move" = "PUT" => from "p_localpath" to "p_remotepath"
-- "p_type_move" = "GET" => from "p_remotepath" to "p_localpath"
-- use ftp server "p_hostname" with usr "p_username" and pwd "p_password"
--
procedure move_file (
p_type_move in varchar2,
p_localpath in varchar2,
p_remotepath in varchar2,
p_filename in varchar2,
p_username in varchar2,
p_password in varchar2,
p_hostname in varchar2,
p_error out varchar2) is
v_exception exception;
p_status varchar2(32000);
p_bytes_trans number;
p_trans_start date;
p_trans_end date;
dummy boolean;
begin
if (p_type_move != 'PUT') and
(p_type_move != 'GET') then
p_error := 'ERROR: value for p_type_move not supported.';
raise v_exception;
end if;
dummy := ftp_interface.verify_server (
p_remotepath => p_remotepath,
p_username => p_username,
p_password => p_password,
p_hostname => p_hostname,
v_status => p_status,
v_error_message => p_error,
p_port => 21,
p_filetype => 'ASCII',
p_mainframe_connection => FALSE );
if p_status != 'SUCCESS' then
raise v_exception;
end if;
if p_type_move = 'PUT' then
dummy := ftp_interface.put (
p_localpath => p_localpath,
p_filename => p_filename,
p_remotepath => p_remotepath,
p_username => p_username,
p_password => p_password,
p_hostname => p_hostname,
v_status => p_status,
v_error_message => p_error,
n_bytes_transmitted => p_bytes_trans,
d_trans_start => p_trans_start,
d_trans_end => p_trans_end,
p_port => 21,
p_filetype => 'ASCII',
p_mainframe_ftp => FALSE,
p_mainframe_cmd => '' );
if p_status != 'SUCCESS' then
raise v_exception;
end if;
elsif p_type_move = 'GET' then
dummy := ftp_interface.get (
p_localpath => p_localpath,
p_filename => p_filename,
p_remotepath => p_remotepath,
p_username => p_username,
p_password => p_password,
p_hostname => p_hostname,
v_status => p_status,
v_error_message => p_error,
n_bytes_transmitted => p_bytes_trans,
d_trans_start => p_trans_start,
d_trans_end => p_trans_end,
p_port => 21,
p_filetype => 'ASCII',
p_mainframe_ftp => FALSE,
p_mainframe_cmd => '' );
if p_status != 'SUCCESS' then
raise v_exception;
end if;
end if;
p_error := 'OK';
exception
when v_exception then
null;
when others then
p_error := 'ERROR: ' || SQLERRM;
end move_file;
La llamada al procedimiento se realiza de manera muy fácil:
move_file('GET',
'/datos',
'/home',
'test.txt',
'usuario',
'password',
'ip_del_host',
v_error);
| Imprimir |

hola muy bueno el articulo, mencionaste el utl_file y yo estoy tratando de armar un excel a partir de una consulta en oracle ej:
select * from tabla
where nombre = ‘jose’;
esta consulta da varios registros como resultados y el excel tendria que quedar asi:
Nombre Apellido Direccion
Jose perez nom 258
Jose fernandez esquin 258
Tipo : contrato
Actualizado el pago.
Todo esto separado en las diferentes columnas del excel. Estuve intentando armar con utl_file pero no con buenos resultados no se si era porq yo lo armaba mal…agradeceria cualquier ayuda..
Desde ya gracias!!
entiendo el problema pero estas viendo la solucion por otro lado, con utl_file no puedes definir que celda de excel va a tener que dato, la solucion es generar un string con los valores separados por algo (comas, pipes, tabulador, etc) y esa cadena la guardas en el archivo linea por linea, al abrir eso en un excel te abre un wizard con opciones de como importar y listo
bien mcuhas gracias ahora mismo me pongo a ver como lo soluciono…muy bueno el blog!!!
espero haberte ayudado, gracias, saludos
¡ Que buen articulo! Felicitaciones. Lo voy a probar a ver si puedo usarlo a futuro en alguna implementación…
gracias, que bueno que les sirva, saludos
Hola, necesito crear un archivo y enviarlo por mail pero no tengo privilegios en el servidor, ni un directorio donde depositarlo, por lo que el utl_file me provoca problemas para encontrar donde dejar el archivo, hay alguna manera de que le diga a Oracle que lo deje en mi maquina y despues lo tome y envie???
con utl_file no tienes acceso a ninguna maquina fuera de donde esta corriendo la base de datos, para usar utl_file forzosamente necesitas los privilegios sobre un directorio de ese servidor
pues tal y como lo harias para otras cosas en windows “e:\directorio\” claro que al ser un paquete en la base de datos este directorio debe de ser del servidor base de datos
como se obtiene?, lee de nuevo el post, saludos
Subi los paquetes del blog y en marca error el procedimiento: ftp_files_stage … tienes otra version o podrias publicar el paquete ftp_interfase que tienes tu para probar move_fle.
Saludos
He probado algunas opciones de copiado de archivos en oracle pero al quer abrir el archivo marca error …
Tienes Idea por que ?
Los txt los pasa como si nada, con los binarios es que copia pero corruptos los archivos…
PROCEDURE UTLTESTCOPY
AS
f1 UTL_FILE.file_type;
BEGIN
f1 := UTL_FILE.fopen (’GESTORDOC_DIR_R’, ‘busq_index.gif’, ‘r’);
UTL_FILE.fcopy (src_location => ‘GESTORDOC_DIR_R’,
src_filename => ‘busq_index.gif’,
dest_location => ‘GESTORDOC_DIR’,
dest_filename => ‘busq_index.gif’
);
UTL_FILE.fclose (f1);
END;
marca error el pakete del blog .. cual usaste proporcionalo
“el paquete del blog” yo inserte el link para la descarga del paquete de una pagina externa, si marca error deberias de investigar mejor el error, a mi me funciono bien como esta
sobre el error al copiar, ya investigaste los demas parametros del procedure “fcopy” de utl_file? se me hace que le tienes que especificar como realizar la copia si ascii o binario (algo como en un cliente ftp)
aparte de esto me queda la duda si realmente es necesario el abrir y cerrar el archivo (fopen y fclose) si solo quieres copiar el archivo, tal vez por ahi valla
hola. estupendo tu artículo. Qué pena que no haya más gente como tú.
Estoy desarrollando una aplicación que requiere que copie un fichero plano de un servidor a otro y tengo unas dudas con respecto a tu artículo.
He montado el paquete de oracleportal en mi servidor desde el que disparo el procedimiento y testeo el move_file con GET, pero exactamente qué directorios hay que poner? los fisicos o los definidos en BD?. El usuario y password son de la bd de destino o del equipo? Puedes usar otro puerto que no sea el 21? Espero no ser muy pesada y reitero mis felicitaciones. un saludo
los directorios son fisicos, del servidor remoto y local, los usuarios son del servidor FTP remoto, el puerto depende del servidor FTP que puerto esta escuchando, saludos
Muy bueno el articulo.
Una pregunta el servidor local o remoto puede ser Windows / Linux? o viceversa?.
Gracias
al estar usando un protocolo como FTP es independiente del sistema operativo, tu te conectas a un servicio remoto en el puerto 21 normalmente y si ese servicio esta sobre un windows, linux, unix, solaris no deberias de tener problemas
Hola Favor tu ayuda, tengo una pantalla en Forms 61,que debe ir ha ver/ buscar un archivo de texto en una ruta del servidor y ese archivo copiarlo localmente
Favor tu ayuda urgente
Gracias
mmm es que directamente esta medio dificil, supongo que al decir “6i” estas trabajando en cliente/servidor por lo que se complica mas, la mas facil que se me ocurre, es que el archivo del servidor lo copies a una tabla de base de datos con UTL_FILE (suponiendo que ese archivo este en el servidor de la base de datos) ya con la info en la base, con text_io de forms generes el archivo localmente, espero haberte ayudado, saludos
no me funciona necesito ftp_interface.verify_server
ftp_interface.put
ftp_interface.get
gracias
lo mejor es que vuelvas a leer el post, saludos
Hola, estoy utilizando el paquete utl_smtp para enviar correos y he visto que se define una variable como utl_tcp.crlf, pero al compilar me da error de restricción de implementación, no se puede acceder a una varible o cursor de paquete remoto. Estoy compialndo en local. Alguien me puede ayudar?
MUchas gracias.
DonZote
Rolate los fuentes que probastes tu, los del articulos no hacen lo que dice que hace.
Subete un ZIP con los fuentes.
Donzonte:
Subete un Zip con los fuentes que probastes, los del articulo no hace lo que dice que hace.
Saludos
esta raro que no funcione, solo que lo hayan cambiado, ya tiene mas de un año que escribi este post, los mejor es que te bajes su ultima version y sobre esa trabajes, igual lo mio se tenga que modificar, saludos
Estimado: no encuentro la libreria ftp_interface,
donde puedo obtenerla!
si leiste el post, seguro sabras de donde se descarga, saludos