Guardando Archivos en una base de datos

Guardando Archivos en una base de datos

Postby lubin » Thu Dec 10, 2020 6:26 pm

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
User avatar
lubin
 
Posts: 449
Joined: Fri Dec 09, 2005 12:41 am
Location: Lima, Peru

Re: Guardando Archivos en una base de datos

Postby leandro » Thu Dec 10, 2020 10:03 pm

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  Expand view

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  Expand view

//CONVERTIMOS EL PDF A CADENA DE TEXTO
fMimeEnc( rutaPDF, rutaTXT )
cText := MemoRead( rutaTXT )
cText := STRTRAN(cText,CRLF,'') 
 
Saludos
LEANDRO AREVALO
Bogotá (Colombia)
https://hymlyma.com
https://hymplus.com/
leandroalfonso111@gmail.com
leandroalfonso111@hotmail.com

[ Embarcadero C++ 7.60 for Win32 ] [ FiveWin 23.07 ] [ xHarbour 1.3.0 Intl. (SimpLex) (Build 20230914) ]
User avatar
leandro
 
Posts: 1669
Joined: Wed Oct 26, 2005 2:49 pm
Location: Colombia

Re: Guardando Archivos en una base de datos

Postby cmsoft » Fri Dec 11, 2020 11:21 am

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..
User avatar
cmsoft
 
Posts: 1285
Joined: Wed Nov 16, 2005 9:14 pm
Location: Mercedes - Bs As. Argentina

Re: Guardando Archivos en una base de datos

Postby lubin » Sat Dec 12, 2020 3:02 am

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
User avatar
lubin
 
Posts: 449
Joined: Fri Dec 09, 2005 12:41 am
Location: Lima, Peru

Re: Guardando Archivos en una base de datos

Postby lubin » Sat Dec 12, 2020 3:08 am

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 ambos casos, 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..
User avatar
lubin
 
Posts: 449
Joined: Fri Dec 09, 2005 12:41 am
Location: Lima, Peru

Re: Guardando Archivos en una base de datos

Postby lubin » Sat Dec 12, 2020 5:26 pm

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 ambos casos, 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..
User avatar
lubin
 
Posts: 449
Joined: Fri Dec 09, 2005 12:41 am
Location: Lima, Peru

Re: Guardando Archivos en una base de datos

Postby leandro » Sun Dec 13, 2020 11:41 am

Amigo como vas?
Para convertir de base64 a su formato normal, debes usar la función inversa.
Code: Select all  Expand view

FMimeDec(rutaTXT ,rutaPDF)
 


Aqui un POST con mas información al respecto
http://forums.fivetechsupport.com/viewtopic.php?f=6&t=30337&p=173596&hilit=fMimeDec#p173596
Saludos
LEANDRO AREVALO
Bogotá (Colombia)
https://hymlyma.com
https://hymplus.com/
leandroalfonso111@gmail.com
leandroalfonso111@hotmail.com

[ Embarcadero C++ 7.60 for Win32 ] [ FiveWin 23.07 ] [ xHarbour 1.3.0 Intl. (SimpLex) (Build 20230914) ]
User avatar
leandro
 
Posts: 1669
Joined: Wed Oct 26, 2005 2:49 pm
Location: Colombia

Re: Guardando Archivos en una base de datos

Postby jnavas » Sun Dec 13, 2020 12:32 pm

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.
viewtopic.php?f=6&t=30337&p=173596&hilit=fMimeEnc&sid=74a41f02acb881c682e2e4b8c607c950#p173596
Juan Navas.
User avatar
jnavas
 
Posts: 479
Joined: Wed Nov 16, 2005 12:03 pm
Location: Caracas - Venezuela

Re: Guardando Archivos en una base de datos

Postby cmsoft » Sun Dec 13, 2020 1:38 pm

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  Expand view

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  Expand view

DescargarArchivo(cUrl,cArchivoFtp,cArchivoLocal)
 


Estas son las funciones
Code: Select all  Expand view

*****************************************
*** 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
User avatar
cmsoft
 
Posts: 1285
Joined: Wed Nov 16, 2005 9:14 pm
Location: Mercedes - Bs As. Argentina

Re: Guardando Archivos en una base de datos

Postby Armando » Sun Dec 13, 2020 4:28 pm

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  Expand view

        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  Expand view

    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
SOI, s.a. de c.v.
estbucarm@gmail.com
http://www.soisa.mex.tl/
http://sqlcmd.blogspot.com/
Tel. (722) 174 44 45
Carpe diem quam minimum credula postero
User avatar
Armando
 
Posts: 3201
Joined: Fri Oct 07, 2005 8:20 pm
Location: Toluca, México

Re: Guardando Archivos en una base de datos

Postby leandro » Mon Dec 14, 2020 7:37 pm

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.
Saludos
LEANDRO AREVALO
Bogotá (Colombia)
https://hymlyma.com
https://hymplus.com/
leandroalfonso111@gmail.com
leandroalfonso111@hotmail.com

[ Embarcadero C++ 7.60 for Win32 ] [ FiveWin 23.07 ] [ xHarbour 1.3.0 Intl. (SimpLex) (Build 20230914) ]
User avatar
leandro
 
Posts: 1669
Joined: Wed Oct 26, 2005 2:49 pm
Location: Colombia


Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 60 guests