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;
}
}
Debe estar conectado para enviar un comentario.