Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   MySQL (https://www.clubdelphi.com/foros/forumdisplay.php?f=21)
-   -   Almacenar y bajar PDF en MYSQL Delphi 2010 desktop (https://www.clubdelphi.com/foros/showthread.php?t=89389)

marvajes 13-11-2015 22:47:56

Almacenar y bajar PDF en MYSQL Delphi 2010 desktop
 
Hola foro, llevo algo de tiempo desarrollando un proyecto para la Universidad. Tengo problema, en los requerimientos del sistema se pide, almacenar archivos en formato PDF(tipo repositorio), los cuales pueden ser cargados(aplicación desktop a mysql ) y descargados(consulta el archivo lo baja y almacena físicamente en una ruta del hd) desde el sistema(aplicación desktop).

He estado investigando al respecto y he logrado cargar un archivo en la base de datos con el siguiente codigo
Código Delphi [-]
  
    SQL.SQL.Add('INSERT INTO ARCHIVO VALUES(:ID,:DATO)');
    SQL.ParamByName('ID').asInteger:= 1;
    SQL.ParamByName('DATO').LoadFromFile('1.pdf',ftblob);
    try
      SQL.Execute;
    finally
        //ERROR
    end;

El archivo se almacena en la tabla Archivo, sin embargo no se si sube archivo de forma correcta, adicional a esto, puedo subir archivos con un tamaño <= 512 kb, al intentar subir archivos mas pesados, el sistema se congela y deja de responder, no se si sea un problema de programación o de la base de datos, ya que tengo entendido que para archivos mas pesados es necesario configurar una variable en mysql.

El asunto es que ya almacenado el archivo, no se como bajarlo por medio de una consulta y almacenarlo en una ruta del disco, para que el usuario pueda consultarlo.
Alguien que pueda apoyarme con este tema, le estaría muy agradecido!.
Trabajo en Windows 7, Mysql, Componente Unidac para establecer la conexión a la BD. (Componente para el query, utilizo unidac, pero no tengo problema al trabajar con ADO, BDE, Interbase, etc)

AgustinOrtu 14-11-2015 01:16:15

Hola marvajes,

Primero que nada en un bloque try-finally, el finally no es donde se captura el "error". El finally es un bloque que se ejecuta luego del try, sin importar si hubo una excepcion, un Break, un Exit, un Continue, etc.

Para catpturar errores, se usa el bloque try-except, asi:

Código Delphi [-]
  try
    { 1 Codigo a ejecutar }
  except
    { 2. Si en 1 se produjo una excepcion, el flujo del programa viene inmediatamente a 2 }
  end;

Para mas info sobre excepciones se suele recomendar el libro "La Cara Oculta de Delphi", que esta en el FTP del club. Tambien hay mogollon de informacion en el foro e internet

Con respecto a tu problema, lo que te falto comentar es como esta definida tu tabla Archivo, no vaya a ser que tenga como limite justamente los 512kb

AgustinOrtu 14-11-2015 01:24:23

Esta es la forma que yo opero con archivos, no es con los componentes UniDAC pero supongo que para todos es la misma,

Para guardarlo:

Código Delphi [-]
var
  LStream: TStream;
begin
  LStream := TFileStream.Create(RutaAlPdf, fmOpenRead);
  try
    Parameters.ParamByName('PDF').LoadFromStream(LStream , ftVarBytes);
  finally
    LStream .Free;
  end;
end;

Para obtener el archivo:

Código Delphi [-]
procedure DownloadPdf(const RutaDescarga: string);
var
  LQuery: TXXXQuery; // componente unidac, ado, etc para ejecutar consultas
begin
  LQuery := .... // crear query, configurar la conexion...
  try
    LQuery.SQL.Text := ' SELECT * FROM Archivo '; // ejecutamos una consulta SQL, podria tener WHERE, etc...
   LQuery.Open; // abrimos
   TBlobField(LQuery.FieldByName('Dato')).SaveToFile(RutaDescarga);
  finally
    LQuery.Free;
  end;
end;

marvajes 14-11-2015 04:06:32

Muchas gracias por la ayuda.
 
Muchas gracias por tu ayuda AgustinOrtu, primeramente por la corrección, pues tenia una idea errónea del uso de try finally.
Con el tema de bajar el archivo, solo hice una pequeña modificación al código.

Insertar el archivo en la Base de datos
Código Delphi [-]
  var
  LStream: TStream;
begin
   SQL.SQL.Add('INSERT INTO ARCHIVOS VALUES(:ID,:DATO)');
   SQL.ParamByName('ID').AsInteger:=1;
   SQL.ParamByName('DATO').LoadFromFile('1.pdf',ftblob);
    try
      Sql.ExecSQL;
    finally
        //ERROR
    end;
end;

Recuperar el archivo y almacenar en disco duro
Código Delphi [-]
var
  LStream: TStream;
begin
  LStream := TFileStream.Create('1.pdf', fmOpenRead);
    Sql.SQL.Add('SELECT * FROM ARCHIVOS');
  try
      SQL.Open; // abrimos
   TBlobField(SQL.FieldByName('NOMBRE')).SaveToFile('C:\u\1.pdf');
  finally
    LStream .Free;
  end;
end;

Cabe mencionar que inicialmente al recuperar el archivo, este aparecia corrupto o no mostraba el contenido y esto debido justamente como indicaste el limite, utilizado inicialmente BLOB ≈ 64KB, MEDIUMBLOB ≈ 16MB and LONGBLOB ≈ 4GB. Lo deje en MEDIUMBLOB y perfecto.
Muchas gracias por la ayuda amigo!.
Saludos.

petercat 07-06-2019 20:38:40

Buenas Leyendo este post me cabe una duda.
Y si en vez de guardar el archivo en una ruta especifica pudiera abrirlo con AcroPDF??
Como podria hacerlo.
Yo puedo abrir archivos pdf desde rutas especificas pero en mi caso quiero abrir dicho archivo pdf pero desde la propia base de datos sin tener que llevarlo a ningun lugar del disco duro.


Esto es posible??

Casimiro Notevi 07-06-2019 22:04:00

Crea un hilo nuevo con tu duda, no aportas nada a la solución de este hilo.
De todas formas, haz una búsqueda por los foros, es un tema que se ha tratado otras veces.
No olvidas repasar nuestra guía de estilo, gracias :)


La franja horaria es GMT +2. Ahora son las 06:38:57.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi