Extracion de documentos en Oracle text

Por Soloelectronicos @soloelectronico

Oracle incorpora un tipo de datos llamado BLOB que permite almacenar documentos de cualquier tipo (imágenes, excel, word, access, comprimidos, vídeos, música, etc). En principio admite cualquier tipo de documento y de cualquier tamaño aunque aún sigue manteniendo el tipo de datos LONG RAW que está obsoleto, sustituido por BLOB. Las instrucciones que os mostramos a continuación admiten ambos tipos de datos: BLOB y LOB RAW.

Insertar o extraer documentos desde Visual Basic

Para poder insertar documentos en un campo BLOB de Oracle con Visual Basic necesitaremos una librería (dll) llamada SAFileMgr Module (SAFileMgr.dll), esta librería está disponible de forma gratuita en la web http://www.softartisans.com. Tras descargar este fichero, deberemos copiarlo a la carpeta del sistema (normalmente C:/Windows/System32) y registrarlo con el comando: regsvr32 C:/Windows/System32/SAFileMgr.dll . Tras copiar y registrar el fichero SAFileMgr.dll, también necesitaremos disponer de una base de datos Oracle activa

Tras tener la tabla creada con el campo BLOB, procederemos a abrir Visual Basic y a crear un nuevo proyecto para insertar y extraer documentos en Oracle. En la ventana de "Nuevo proyecto" seleccionaremos "EXE estándar" y pulsaremos "Abrir":Para que la aplicación funcione correctamente deberemos agregar las referencias necesarias. Para ello pulsaremos en el menú "Proyecto " - "Referencias" de Visual Basic:Seleccionaremos la referencia :Si no aparece en la lista, pulsaremos en Examinar y seleccionaremos el fichero .dll copiado y registrado anteriormente: C:/Windows/System32/SAFileMgr.dll y seleccionaremos también Microsoft ActiveX Data Objects 2.6 Library: Si no aparece en la lista, pulsaremos en Examinar y seleccionaremos el fichero ubicado en: C:/Archivos de programa/Archivos comunes/system/ado/msado26.tlb

Ahora veamos el código de cada uno de los tres botones de un formulario tipo para lanzar una consulta de inserción o extracción de un documento :

    Para el botón "Insertar documento":
Private Sub btInsertarDocumento_Click() Dim Conn As New ADODB.Connection Dim Rs As New ADODB.Recordset Dim FileMgr As New FileManager Dim SQL As String On Error GoTo cError ' Conexión mediante OLEDB Conn.Provider = "OraOLEDB.Oracle" Conn.Open txtServicio.Text, _ txtUsuario.Text, txtContrasena.Text ' Ejecutamos una consulta SQL sobre la tabla para activar el recordset SQL = "Select * from " + txtTabla.Text + " where 1=2″ Rs.Open SQL, Conn, 2, 3 ' Añadimos un nuevo registro con los datos indicados Rs(txtCampoTitulo.Text).Value = txtDocumentoTitulo.Text Rs(txtCampoRutaDocumento.Text).Value = txtDocumento.Text ' Insertamos el documento en el campo BLOB/RAW FileMgr.ExportToBlob txtDocumento.Text, Rs(txtCampoBLOB.Text) Set Conn = Nothing MsgBox "Documento insertado correctamente en " + MsgBox Err.Description GoTo cSalir Private Sub btEjecutar_Click() Dim Conn As New ADODB.Connection Dim Rs As New ADODB.Recordset On Error GoTo cError ' Conexión a Oracle mediante OLEDB Conn.Provider = "OraOLEDB.Oracle" Conn.Open txtServicio.Text, ' Ejecutamos consulta SQL introducida por el usuario Rs.Open txtSQL.Text, Conn, 0, 1 txtExtraerTitulo.Text = Rs(txtCampoTitulo.Text) txtDestino.Text = Rs(txtCampoRutaDocumento.Text) Set Conn = Nothing MsgBox "Consulta SQL ejecutada correctamente.", MsgBox Err.Description GoTo cSalir Private Sub btExtraer_Click() Dim Conn As New ADODB.Connection Dim Rs As New ADODB.Recordset Dim FileMgr As New FileManager Dim continuar As Boolean On Error GoTo cError ' Conexión a Oracle mediante OLEDB Conn.Provider = "OraOLEDB.Oracle" Conn.Open txtServicio.Text, _ txtUsuario.Text, txtContrasena.Text ' Ejecutamos consulta SQL introducida por el usuario Rs.Open txtSQL.Text, Conn, 0, 1 ' Comprobamos si existe ya un fichero destino ' con el mismo nombre continuar = False If Dir(txtDestino.Text) <> "" Then continuar = MsgBox("Ya existe un documento " + continuar = True ' Extraemos el documento del primer registro de la consulta SQL en el destino especificado por el usuario If continuar Then FileMgr.ImportFromBlob Rs(txtCampoBLOB.Text), txtDestino.Text MsgBox "Fichero extraído correctamente en: " + vbCrLf + vbCrLf + txtDestino.Text, vbOKOnly + vbInformation Set Conn = Nothing MsgBox Err.Description GoTo cSalir "con este nombre ¿desea reemplazarlo?", vbYesNo + vbQuestion) = vbYes vbOKOnly + vbInformation txtUsuario.Text, txtContrasena.Text "la base de datos: " + vbCrLf + vbCrLf + txtDocumento.Text, vbOKOnly + vbInformation

Extracción desde java

Ahora veamos usando el lenguaje Java un ejemplo de como podemos extraer documentos almacenados en CLOB's en una base de Datos Oracle Text 9 en Java

Necesitaremos tener instalado el cliente Oracle instalado en la maquina, las credenciales de acceso , asi como referenciar en el proyecto desde el Eclipse las siguientes librerías

Y ahora veamos un ejemplo de una clase de extracción de campos clob's

La clase principal es Main , la cual debería seleccionarse al exportar el proyecto desde Eclipse

Se puede ejecutar en local o crear un pequeño script para invocar el java

En este ejemplo es obligatorio usar tres argumentos y en este orden para llamar al programa:

  • nodo= número del nodo a exportar
  • tope = numero de orden donde se quedo la última exportación empezando por cero
  • topefinal= umbral donde termina

En el proyecto se han referenciado dos versiones de la MV Java porque puede ocurrir que la MV usada en local ( 1.6 ) sea diferente a la del host donde se ejecute ( por ejemplo la 1.4.2_08, razon por la habria que copiar tambien esa version 1.4.2.08 dedseel host a una ruta local

También se hace referencia al driver de oracle classes12.jar , ruta que también existe en la maquina

Este proyecto debería exportarse situándose en la raiz del proyecto como un jar sin incluir tanto los ficheros .classspath como el de .project

Antes de compilar debe eliminar manualmente el war existente desde el propio eclipse asi como el log de ejecución (manualmente habría que ubicarse en c:\ users\xxx\workspace\application)

Asimismo por ultimo , al compilarlo no debemos incluir el classpath

Veamos el código completo;

*/

import java.io.IOException;
import java.io.InputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.ResultSet;
import oracle.jdbc.driver.OracleDriver;

public class Main {

private static int nodo;

private static int tope;

private static int topefinal;

public static void main(final String[] args) {

// Comprueba si hay argumentos en la linea de comandos

System.out.println("Inicializando programa ...");

Connection conn = null;

GestorDeConexiones gc = null;

try{

gc = new GestorDeConexiones("xxxx", "yyyyyy"); // credenciales de acceso a la BBDD con el user y pwd de acceso

conn = gc.getConnection();

final int nnodo=1;

if(args.length != 0)
//CON ARGUMENTOS

System.out.println(" fin argumentos");

//SIN ARGUMENTOS

nodo = Integer.parseInt(args[0]); // primer argumento ( el nodo)

tope = Integer.parseInt(args[1]); //segundo argumento (inicio

topefinal = Integer.parseInt(args[2]); //tercer argumento ( tope)

//generacion del fichero de salida

System.out.println("Argumento nodo= " + nodo);
System.out.println("Argumento conteo incial= " + tope);
System.out.println("Argumento numero de documentos= " + topefinal);

}

else

System.out.println("NODO" + nodo);
System.out.println("Valor inicial= " + tope);
System.out.println("Valor final= " + topefinal);

//creacion fichero de log

final String path1 ="d:\";

final String nfichero= path1+"previa_carga_jd_"+nodo+" tope "+tope+"topefinal_"+ topefinal;

File theDir = new File(nfichero);

if (!theDir.exists())
{
System.out.println("..creando directorio: " + theDir.getName()); // SI EL DIRECTORIO NO EXISTE ,. SE CREA
boolean result = false;
try{
theDir.mkdir();

result = true;
}
catch(SecurityException se){ //handle it
}
if(result) {
System.out.println("Directorio creado");
}
}

//Intentamos cambiar los permisos al directorio creado
System.out.println("Cambiamos permisos 777 a "+nfichero);
Process theProcess = null;
try
{
theProcess = Runtime.getRuntime().exec("chmod 777 "+ nfichero);
}
catch(IOException e)
{
System.out.println("Error en el método exec()");
}

final String log1=path1;

final String nfichero1= log1+"directorio_"+nodo+" tope "+tope+"topefinal_"+ topefinal+".log";

System.out.println("Fichero Log de proceso :[" +nfichero1+"]");
System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");

//generación del fichero de salida

File fichero = new File(nfichero1);

if (!fichero.exists())
{

// SI NO EXISTE , SE CREA
System.out.println("..creando fichero de log: " + fichero.getName());
boolean result = false;
try{
fichero.createNewFile();

result = true;
}
catch(SecurityException se){ //handle it
}
if(result) {
System.out.println("Fichero creado");
}
}

//abre fichero de log
File TextFile = new File(nfichero1);
FileWriter TextOut = new FileWriter(TextFile, true);
TextOut.write("********************************************************************\r\n");
TextOut.write("INICIANDO PROCESO DE EXTRACCIÓN DE DOCUMENTOS r\n");
TextOut.write("Fichero Log de proceso :[" +nfichero1+"]\r\n");
TextOut.close();

String path=nfichero +"/";

System.out.println ("RUTA DESTINO FINAL"+ path);

//extraemos los objetos de texto
RecuperadorBD2.RecuperarBD2(conn,path, tope,topefinal,nodo,nfichero1);

}
catch (final SQLException sqle) {
System.out.println
("Error de acceso a BD:" + sqle.getMessage());
sqle.printStackTrace();
}
catch (final IOException ioe){
System.out.println
("Error de acceso a disco:" + ioe.getMessage());
ioe.printStackTrace();
}

catch (final SQLException sqle)
{
System.out.println
("Error de acceso a BD:" + sqle.getMessage());
sqle.printStackTrace();
conn = null;
gc = null;
}
System.out.println(" **** Fin extraccion ****");
}
}

String topex1= String.valueOf(topex);

String topec1= String.valueOf(topec);

String nnodo= String.valueOf(nodo);

int contador=0;
FileOutputStream fos = null;

Statement st = null;
ResultSet rs = null;

final String sql=" SELECT "+
"FROM(SELECT to_number (rownum) cuenta,"+
" p.
"+
" FROM "+
" ( "+
"SELECT c.nodo_co_nodo, "+
" c.infi_nu_infi, "+
" c.docu_co_documento, "+
" d.docu_no_documento, "+
" d.docu_no_extension ,"+
" d.docu_nu_version, "+
" d.DOCU_FX_MODIFICACION fecha,"+
" e.doct_do_documento doc "+
" FROM tablametadatos c, "+
" tablaauxiliar d, "+
" tabladocumentos e "+
" WHERE c.nodo_co_nodo = " + nnodo +
" AND c.docu_co_documento =d.docu_co_documento "+
" AND d.docu_co_documento =e.docu_co_documento "+
" AND e.docu_nu_version =d.docu_nu_version "+
" AND c.docu_nu_version =e.docu_nu_version "+
" ) "+
" where (cuenta >"+topec1 + " and cuenta <" +topex1 +" )";

//abre fichero de log
File TextFile = new File(path1);
FileWriter TextOut = new FileWriter(TextFile, true);

TextOut.write("********************************************************************\r\n");
TextOut.write("COMENZANDO PROCESO INICIAL\r\n");
TextOut.write("sql general="+sql+"\r\n");

st = cn.createStatement();
rs = st.executeQuery(sql);

while (rs.next())
{
++contador;
//para blobs
final String verdocu= rs.getString("docu_no_documento") ;
System.out.println("Ndocu =" + verdocu );

final String verinfi =rs.getString("infi_nu_infi");
System.out.println("Infi =" + verinfi );

final String verloc = rs.getString("docu_co_documento");
System.out.println("Cdocc =" + verloc );

final String vernombre= verinfi+" "+verloc + " "+ verdocu;

System.out.println("Nombre =" + vernombre );

System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
System.out.println("Numero fichero a extraer =" + contador );

TextOut.write("Numero fichero a extraer =" + contador+"\r\n");

final String nfichero =vernombre; //LE PASAMOS COMO ARGUMENTO EL NOMBRE YA MONTADO:INFI_DOCU+LOC

System.out.println(" Fichero a extraer: " +nfichero);
TextOut.write("Fichero a extraer =" + nfichero+"\r\n");

final String pathname= path + nfichero ;
System.out.println(" Extrayendo fichero multimedia : "+pathname);
TextOut.write("Extrayendo fichero multimedia =" + pathname +"\r\n");

//deberíamos comprobar si existe ese fichero
final File file = new File(pathname);

final byte[] buffer = new byte[size];
int length = -1;

if (fos != null)

{

//Intentamos cambiar los permisos al directorio creado
TextOut.write("Fichero extraido ok \r\n");

}
}
}
catch (final IOException ioe)
{
throw new IOException(ioe.getMessage());

System.out.println("Fin RecuperaBD2");

System.out.println("FIN PROCESO") ;

//clase para gestionar las conexiones con la BBDD

TextOut.close();

//funcion para añadir permisos 777 a los ficheros extraidos
public static void permisos777 (final String pathname)
{

Process theProcess = null;

//intentamos cambiar los permisos del fichero recién creeado
System.out.println("Cambiamos permisos 777 a "+pathname);
try
{
theProcess = Runtime.getRuntime().exec("chmod 777 "+ pathname);
}
catch(IOException e)
{
System.out.println("Error en el método exec()");
}
//fin de cambio de permisos

}

}

class GestorDeConexiones
{
private final String user;
private final String password;
private Connection conn = null;
private boolean conectado = false;

private void conectar() throws SQLException {

String url;
DriverManager.registerDriver(new OracleDriver());

url = "jdbc:oracle:thin:@x.x.x.x:yyy:cadena"; ///ojo PROD

conn = DriverManager.getConnection(url,user, password);
System.out.println("Conexion correcta");
conectado = true;

}

public Connection getConnection() throws SQLException
{
if (!conectado)
conectar();
return conn;
}
}