Extracion de documentos en Oracle text


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 FileMgr 1.1: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.AddNew

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)

Rs.Update

Rs.Close

Conn.Close

Set Conn = Nothing

MsgBox “Documento insertado correctamente en ” + “la base de datos: ” + vbCrLf + vbCrLf + txtDocumento.Text, vbOKOnly + vbInformation

cSalir:

Exit Sub

cError:

MsgBox Err.Description

GoTo cSalir

End Sub

  • Para el botón “Ejecutar“:

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,  txtUsuario.Text, txtContrasena.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)

Rs.Close

Conn.Close

Set Conn = Nothing

MsgBox “Consulta SQL ejecutada correctamente.”,  vbOKOnly + vbInformation

cSalir:

Exit Sub

cError:

MsgBox Err.Description

GoTo cSalir

End Sub

  • Para el botón “Ejecutar“:

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 ” + “con este nombre ¿desea reemplazarlo?”, vbYesNo + vbQuestion) = vbYes

Else

continuar = True

End If

‘ 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

End If

Rs.Close

Conn.Close

Set Conn = Nothing

cSalir:

Exit Sub

cError:

MsgBox Err.Description

GoTo cSalir

End Sub

 

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;

 

/*
Main.java
*
* Created on 20 de Marzo de 20174, 11:43
*

*/

import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;

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;

/**
* @author CRN
*
* EXTRACTOR DOCUMENTOS
*/

public class Main {

private static int nodo;

private static int tope;

private static int topefinal;

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

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();

// Comprueba si hay argumentos en la linea de comandos

final int nnodo=1;

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

{
for(int counter = 0; counter < args.length; counter++)
{
System.out.println(“Argument index ” + counter + “: ” + args[counter]);
}

System.out.println(” fin 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)

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

}

else

//SIN ARGUMENTOS

{
System.out.println (“No se ha incluido ningún argumento”);
System.exit(0);
}

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

final String path1 =”d:\”;

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

//generacion del fichero de salida

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()”);
}

//creacion fichero de log

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();
}

try{
if (gc != null && conn != null)
gc.closeConnection();
}

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 ****”);
}
}

class RecuperadorBD2
{
public static void RecuperarBD2 (final Connection cn, final String path , final int topec, final int topex, final int nodo ,final String path1)
throws SQLException, IOException
{

 

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);

System.out.println(“”);
System.out.println(“********************************************************************”);
System.out.println(“COMENZANDO PROCESO INICIAL”) ;
System.out.println(“sql general=”+sql);
System.out.println(“”);

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

try
{

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);

fos = new FileOutputStream(file);
final Blob bin = rs.getBlob(“doc”);
System.out.println(“…Extrayendo BLOB”);
TextOut.write(“Extrayendo BLOB \r\n”);

final InputStream inStream = bin.getBinaryStream();
final int size = (int)bin.length();
System.out.println(“Tamaño: “+size);
TextOut.write(“Tamaño =” + size+”\r\n”);

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

while ((length = inStream.read(buffer)) != -1)
{
fos.write(buffer, 0, length);
}

if (fos != null)

{

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

permisos777(pathname);
fos.close();
System.out.println(” Fichero extraido ok.”);
System.out.println(“+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++”);
TextOut.write(“+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n”);

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

}
finally
{
if (fos !=null)
{
fos.close();
TextOut.write(“FIN DEL PROCESO \r\n”);
TextOut.close();

}
if (rs !=null)
{
rs.close();

TextOut.close();
}
rs=null;
st=null;

 

 

System.out.println(“Fin RecuperaBD2”);

System.out.println(“FIN PROCESO”) ;

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

}

}

//clase para gestionar las conexiones con la BBDD

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

public GestorDeConexiones(final String usr, final String pwd){
user = usr;
password = pwd;
}

public void closeConnection() throws SQLException{
if (conectado)
conn.close();
}

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;
}
}