Page 1 of 1

Guardando Archivos en una base de datos

Posted: Thu Dec 10, 2020 6:26 pm
by lubin
Buen dia con todos


Muchas veces tengo por ejemplo en una tabla una relacion de facturas y por cada factura hay documentos fisicos scaneados como cotizaciones, pedidos, contratos


Resulta que Yo guardaba los documentos (archivos jpg, docx, pdf.. etc) en una carpeta en el disco y en la tabla de facturas, guardaba en un campo su rutas donde estaban y que tenia... asi el usuario si deseaba consultar por un contrato de esa factura entraba a la factura y click encontraba el contrato y lo jalaba a pantalla.

Hasta ahi todos felices... pero resulta que ahora me veo en la necesidad de "guardar los documentos" en una tabla para incluir los documentos en la base de datos y poder consultarlos en forma REMOTA, (Bendita pandemia... !!!)

he pensado solo una tabla con esta estructura
Todo lo trabajo en MySQL 5.2 :

campoKey Chr 20 "Para enlazarlo con el documento"
TipoDocum Chr 04 "para saver .. word,exce,pdf, jpg.. "
DescriDocum Chr 30 "Descripcion"
Contenido longblob "para guardar los archivos"

Alguien almacena documentos dentro de un MYSQL, de esta manera u otra manera, ??? es seguro u opertivo hacerlo asi, Algun ejemplo como lo grabo en la tabla de la base de datos.

Gracias :

Lubin

Re: Guardando Archivos en una base de datos

Posted: Thu Dec 10, 2020 10:03 pm
by leandro
Amigo como estas... si claro que si

Si se puede hacer sin problemas, lo único que debes considerar es el momento de la consulta, no jalar demasiada información, ya que el peso de esos archivos, hará que la consulta tarde demasiado.

Code: Select all

CREATE TABLE IF NOT EXISTS soportes
    (
    id_factura INT auto_increment,
    id_cliente INT NOT NULL, 
    pdf MEDIUMTEXT, 
    estado_documento INT NOT NULL, 
    PRIMARY KEY (id_factura),
    FOREIGN KEY (id_cliente ) REFERENCES clientes (id_cliente )  
    )
 
Así convierto los archivos antes de registrarlos en la base de datos

Code: Select all

//CONVERTIMOS EL PDF A CADENA DE TEXTO
fMimeEnc( rutaPDF, rutaTXT )
cText := MemoRead( rutaTXT )
cText := STRTRAN(cText,CRLF,'') 
 

Re: Guardando Archivos en una base de datos

Posted: Fri Dec 11, 2020 11:21 am
by cmsoft
Lubin, tambien, si tenes la base de datos en un servidor, podrías subir los archivos por FTP, entonces no te ocuparían espacio en la base de datos..

Re: Guardando Archivos en una base de datos

Posted: Sat Dec 12, 2020 3:02 am
by lubin
Hola Leandro

Efectivamente al momento de de hacer el Browse de las Facturas solo cargo la data sin las imagenes, y solo cuando soliciten ver o descargar el Archivo, le aplicare un SELECT a ese registro y Campo "Xcontenido" para mostrarlo. hace tiemo hice un file de productos con su foto, pero al crecer la base de datos ,, se pudo demasiado lenta por cargar las fotos en el browse..

Ahi ahora viene el detalle, en la rutina que me muestras, es para cargar un Archivo PDF, de ahi viene el tema .. se supone que el Usuario desesa descargarlo, cual seria e procedimiento, pues veo para guardarlo hay una transfomracion,, y para hacer lo inverso como lo descargo.

Por otro lado, comentas perfecto el caso de PDF, pero si tambien deseo guardar un archivo Word, Excel o Jpg, hay otra funciones para convertirlos y guardarlos. o habra un metodo generico ??? sobre todo tambien ver luego su descarga.

Buen aporte Leandro.. voy avanzando.

Gracias
Lubin

Re: Guardando Archivos en una base de datos

Posted: Sat Dec 12, 2020 3:08 am
by lubin
Buenas noches Cesar

Si esa alternativa también la pensé, pero no tengo experiencia en esto del FTP, entiendo que es tener acceso a una"Carpeta" en el servidor de la nube, la idea no es mal tampoco pero tendría que ver también _, su almacenamiento y/o luego su descarga si el Usuario pide el archivo para tenerlo o visualizarlo

De hecho actualmente lo hago en mi servidor local de mi oficina, pero eso es mas fácil , es un simple copy del Archivo a la carpeta, quizas tengas algun ejemplo de la operacion en FTP?

Estimado Gracias por su tiempos.

Lubin
cmsoft wrote:Lubin, tambien, si tenes la base de datos en un servidor, podrías subir los archivos por FTP, entonces no te ocuparían espacio en la base de datos..

Re: Guardando Archivos en una base de datos

Posted: Sat Dec 12, 2020 5:26 pm
by lubin
Hola Cesar

Estuve dando una mirada por el foro y vi un par de ejemplos del uso del FTP, probare si es efectvos,, pero como dicen la La experiencia es sabia si algo has probabo.. bienvenido sea

Saludos

lubin wrote:Buenas noches Cesar

Si esa alternativa también la pensé, pero no tengo experiencia en esto del FTP, entiendo que es tener acceso a una"Carpeta" en el servidor de la nube, la idea no es mal tampoco pero tendría que ver también _, su almacenamiento y/o luego su descarga si el Usuario pide el archivo para tenerlo o visualizarlo

De hecho actualmente lo hago en mi servidor local de mi oficina, pero eso es mas fácil , es un simple copy del Archivo a la carpeta, quizas tengas algun ejemplo de la operacion en FTP?

Estimado Gracias por su tiempos.

Lubin
cmsoft wrote:Lubin, tambien, si tenes la base de datos en un servidor, podrías subir los archivos por FTP, entonces no te ocuparían espacio en la base de datos..

Re: Guardando Archivos en una base de datos

Posted: Sun Dec 13, 2020 11:41 am
by leandro
Amigo como vas?
Para convertir de base64 a su formato normal, debes usar la función inversa.

Code: Select all

FMimeDec(rutaTXT ,rutaPDF)
 
Aqui un POST con mas información al respecto
http://forums.fivetechsupport.com/viewt ... ec#p173596

Re: Guardando Archivos en una base de datos

Posted: Sun Dec 13, 2020 12:32 pm
by jnavas
Saludos
Desarrollé esta implementacion para MySQL y hemos logramos implementarlo con MSSQL, publiqué este ejemplo utilizando tablas DBF, hemos logrado almacenar imágenes, binarios, videos, otros archivos pesados.
http://fivetechsupport.com/forums/viewt ... 50#p173596
Juan Navas.

Re: Guardando Archivos en una base de datos

Posted: Sun Dec 13, 2020 1:38 pm
by cmsoft
Para subir archivos al ftp uso funciones que creo tome del foro:
cServidorFtp es el servidor ftp donde tienes que conectar
cUser y cPassword serán tus credenciales de conexión
cArchivoOrigen es el archivo que quieres subir
cUrl es la carpeta dentro del servidor FTP donde quieres dejar el archivo
cArchivoDestino es como quieres llamar el archivo dentro del sitio ftp (Aqui puedes hacer igual que como hacias con las dbfs, dejar en la tabla el nombre del archivo con que lo dejas en el ftp)

Code: Select all

IF !ConectaServerFTP(cServidorFtp,cUser,cPassword,@oFtp)
    MsgStop("No pudo conectar")
    else 
    SubeArchivoFtp(cArchivoOrigen,cUrl+cArchivoDestino,oFtp)
ENDIF 
 
Para leer los archivos uso la siguiente funcion:

Code: Select all

DescargarArchivo(cUrl,cArchivoFtp,cArchivoLocal)
 
Estas son las funciones

Code: Select all

*****************************************
*** Conectar al servidor FTP
FUNCTION ConectaServerFTP(cNomSer,cNomUsr,cClaUsr,oFtp)
LOCAL cServer, cUser, cPassword, oUrl, cUrl
cServer := cNomSer //change ftpserver to the real name or ip of your ftp server
cUser := cNomUsr // change ftpuser to an valid user on ftpserer
cPassword := cClaUsr // change ftppass to an valid password for ftpuser
cUrl := "ftp://" + cUser + ":" + cPassword + "@" + cServer
cUser:= strtran(cUser,"@","&at;")
oUrl := tUrl():New( cUrl )
IF At( "@", cUser ) > 0
   oUrl:cUserID := strtran(cUser,"&at;","@")
   oUrl:cPassword := cPassword
ENDIF
oFTP := tIPClientFtp():New( oUrl, .T. )
oFTP:nConnTimeout := 20000
oFTP:bUsePasv := .T.
oFtp:bTrace := {|| .t.}
oFTP:Open( )
IF oFtp <> NIL
   RETURN .T.
ENDIF
RETURN .F.

FUNCTION SubeArchivoFtp(cFileOri,cFileDes,oFtp)
oFtp:Dele( cFileDes )
oFtp:UpLoadFile( cFileOri, cFileDes )
RETURN .T.

***************************************
** Descargar archivo desde ftp
function DescargarArchivo(url,cArchivoFtp,cArchivoLocal)
LOCAL nRet
DELETEURLCACHEENTRY(  Url+cArchivoFtp)
nRet := DOWNLOADFILE( url+cArchivoFtp, cArchivoLocal)
RETURN nRet = 0


#pragma BEGINDUMP


#include <Windows.h>
#include <hbapi.h>
#include <urlmon.h>

HB_FUNC( DOWNLOADFILE )

{
        HRESULT hr;
       
        hr = URLDownloadToFile( NULL, hb_parc( 1 ), hb_parc( 2 ), 0, NULL ) ;
       
        hb_retnl( hr ) ;
}


#pragma ENDDUMP

DLL STATIC FUNCTION DELETEURLCACHEENTRY( cUrl AS LPSTR ) AS BOOL;
PASCAL FROM "DeleteUrlCacheEntryA" LIB "wininet.dll"
 
El proceso es efectivo, funciona bien, teniendo en cuenta que debe conectarse al ftp y subir el archivo. No es rapido pero funciona...
Tal vez algún alguien mas entendido que yo pueda mejorar las funciones.
Espero te sirva

Re: Guardando Archivos en una base de datos

Posted: Sun Dec 13, 2020 4:28 pm
by Armando
Lubin:

Como ves, hay varias formas de guardar archivos en una tabla, aquí te va la
que yo utilizo y va de 100%.

Para guardar:

Code: Select all

        cPdfFile := StrToHex(MemoRead(oOdc:FIL))
        nUltSec++

        cCmdSql := "INSERT INTO " +;
                            "OdcCpa " +;
                        "SET " +;
                            "ODC_SER = '" + oRsHdr:Fields("HDR_SER"):Value + "'," +;
                            "ODC_COT = " + STR(oRsHdr:Fields("HDR_COT"):Value,07,0) + "," +;
                            "ODC_SEC = " + STR(nUltSec,02,0) + "," +;
                            "ODC_ODC = '" + oOdc:ODC + "'," +;
                            "ODC_FDE = '" + DTOS(oOdc:FDE) + "'," +;
                            "ODC_PDF = '" + cPdfFile + "'," +;
                            "ODC_IOC = " + STR(oOdc:IOC,11,2)

    TRY
        oApp:oCon:Execute(cCmdSql)
    CATCH oError
        MsgInfo("No pude ejecutar el comando " + cCmdSql,oApp:cAplicacion)
        ShowError(oError)
        RETURN(.F.)
    END
 

Ahora para "sacar" el archivo guardado

Code: Select all

    IF oRsOdc:Fields("ODC_PDF"):Value != NIL
        cFile := oApp:cPathPdfs + "\1A" + SUBSTR(TIME(),1,2) + SUBSTR(TIME(),4,2) + SUBSTR(TIME(),7,2) + ".Pdf"

        IF File(cFile)
           Ferase(cFile)
        ENDIF

        //Se traduce y se graba un archivo temporal en disco
        oHandle := FCreate(cFile)
        FWrite(oHandle, HexToStr(oRsOdc:Fields("ODC_PDF"):Value))
        FClose(oHandle)

        IF FSize(cFile) > 0
                ShellExecute(0,"Open",cFile,,,1)
        ENDIF
    ENDIF
 
Lo he utilizado con archivos PDF pero creo que no tendrás problemas
con cualquier otro tipo de archivo.

Toma en cuenta que guardar archivo en las tablas consumen muchos recursos, entonces
tiene su lado bueno esta práctica pero también tiene su lado malo.

Saludos

Re: Guardando Archivos en una base de datos

Posted: Mon Dec 14, 2020 7:37 pm
by leandro
Amigo otra ventaja que tienes de hacerlo con las funciones mime (base64), es que lo puedes convertir fácilmente desde cualquier lenguaje de programación, por si deseas mostrar esa información en la nube.