Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Guardar un archivo PDF en un campo de MS SQL Server 2008 R2. (https://www.clubdelphi.com/foros/showthread.php?t=78006)

TiammatMX 12-03-2012 19:18:36

Guardar un archivo PDF en un campo de MS SQL Server 2008 R2.
 
Buen día, jóvenes delphineros:

Les platico mi problema. El usuario para el que estoy programando desea, más bien, exige poder guardar una serie de archivos *.PDF en varios registros de una tabla de MS SQL Server 2008 R2 (el campo definido como binary), por que desea mostrarlos en una miniatura y tenerlos siempre a mano. Yo estoy plenamente consciente que guardar ésos archivos convertiría la base de datos en un monstruo, pero así lo quieren.

Estuve haciendo una primera aproximación a cómo debería ser el guardado de los datos, pero obviamente no funciona y es donde yo recurro a la sabiduría compartida del grupo, para que me asesoren y/o colaboren en la solución de ésta tarea.

Código Delphi [-]
procedure TfrmContenedor.btnImportarClick(Sender: TObject);
var
  sNombreArchivo : string;
  fsPDF : TStream;
  bfCampo : TBlobField;
begin
  sNombreArchivo := '';
  with dlgAbrirArchivo do
  begin
    InitialDir := ExtractFilePath(Application.ExeName);
    Filter := 'Archivos de Adobe Acrobat (*.pdf)|*.PDF';
    Title := 'Buscar archivos de documentos para el paciente.';
    DefaultExt := '*.pdf';

    if Execute then
      sNombreArchivo := FileName;
  end;

  if sNombreArchivo <> '' then
  begin
    fsPDF := TFileStream.Create(sNombreArchivo,fmOpenRead);
    bfCampo := TBlobField.Create(Self);
    with tblPDFs do
    begin
      fsPDF.Read(bfCampo,fsPDF.Size);
      Connection := qryDocumentos.Connection;
      TableName := 'HY11_DocumentosPacElec';
      Open;
      try
        Insert;
        strngfldPDFsE2_CTRL_PAC.Value := lblExpediente.Caption;
        intgrfldPDFsC42_Documento_ID.Value := StrToInt(Texto2ID(chklstDocumentos.Items.Strings[chklstDocumentos.ItemIndex]));
        bytsfldPDFsHY11_DocumentoElectronico.GetData(bfCampo);
        Post;
      finally
        Close;
      end;
    end;
    fsPDF.Destroy;
    bfCampo.Destroy;
  end;
end;

Nuevamente, se requiere necesariamente que el archivo sea guardado en una tabla. Acepto cualquier tipo de ayuda, hasta apoyo moral.

De antemano, gracias.

olbeup 14-03-2012 11:10:10

Hola Tiammat

Actualmente grabo las fotos y los pdf's dentro de la base de datos, como bien dices, para tenerlas siempre a mano y en cualquier momento.

La función que utilizo funciona correctamente, actualmente utilizo SQL SERVER 2005 sin ningún problema ni error de grabación o recuperación del fichero, tanto JPG o PDF.

Esta función trabaja directamente con un ADOQuery ya definido y conectado a la DB.

Cita:

Devuelve un fichero temporal único
Código Delphi [-]
function GetNewFileTemp(Prefix: String): String;
var
  PathTmp: Array[0..MAX_PATH] of Char;
  FileTmp: Array[0..MAX_PATH] of Char;
begin
  FillChar(PathTmp, SizeOf(PathTmp), #0);
  FillChar(FileTmp, SizeOf(FileTmp), #0);

  GetTempPath(MAX_PATH, PathTmp);
  GetTempFileName(PathTmp, PChar(Prefix), 0, FileTmp);

  Result := FileTmp;
end;

Cita:

Devuelve el pdf del campo query que está activo en ese momento
Código Delphi [-]
function GetFieldDBToPDF(QryDB: TADOQuery): WideString;
var
  Stream: TMemoryStream;
  FileTmp: String;
begin
  Stream := TMemoryStream.Create;
  FileTmp := GetNewFileTemp('~t1');
  try
    TBlobField(QryDB.FieldByName('PDFIMAGEN')).SaveToStream(Stream);
    Stream.Position := 0;
    Stream.SaveToFile(FileTmp);
  finally
    Stream.Free;
  end;
  Result := FileTmp;
end;

Cita:

Graba en el campo query que está activo en ese momento el PDF
Código Delphi [-]
procedure UpdatePDFToFieldDB(QryDB: TADOQuery; Filename: WideString);
var
  Stream: TMemoryStream;
begin
  Stream := TMemoryStream.Create;
  Stream.LoadFromFile(FileName);
  try
    QryDB.Edit;
      (QryDB.FieldByName('PDFIMAGEN') as TBlobField).Clear;
      (QryDB.FieldByName('PDFIMAGEN') as TBlobField).LoadFromStream(Stream);
    QryDB.Post;
  finally
    Stream.Free;
  end;
end;

Cita:

Añade en el campo query que está activo en ese momento el PDF
<Parametros>, ADOQuery, Filename, FieldNameID, FieldValueID
Código Delphi [-]
procedure AddPDFToFieldDB(QryDB: TADOQuery; Filename: WideString; FieldNameID: String; FieldValueID: Integer);
var
  Stream: TMemoryStream;
begin
  Stream := TMemoryStream.Create;
  try
    if (Length(Filename) > 0) then
    begin
      Stream.LoadFromFile(FileName);
      QryDB.Append;
      QryDB.Edit;
        (QryDB.FieldByName('PDFIMAGEN') as TBlobField).Clear;
        (QryDB.FieldByName('PDFIMAGEN') as TBlobField).LoadFromStream(Stream);
        QryDB.FieldByName(FieldNameID).AsInteger := FieldValueID;
      QryDB.Post;
    end
    else begin
      QryDB.Edit;
        (QryDB.FieldByName('PDFIMAGEN') as TBlobField).Clear;
      QryDB.Post;
    end;
  finally
    Stream.Free;
  end;
end;
Este último utilizo el FieldNameID para hacer referencia algún campo de la base de datos FieldValueID es el valor que debe tomar.
Eje.
Si se añade un registro en una DB de ITVPDF ésta DB los campos que tienen son (IDITVDF, PDFIMAGEN, ITVID), el FieldNameID = ITVID y el valor de éste es el FieldValueID = ITVID, ésta función la utilizo para varias DB distinstas, donde el FieldNameID puede variar, por esta razón se envía el campo y el valor.

Estas funciones han sido realizadas gracias a las muchas respuestas sobre el tema en esta comunidad ClubDelphi.

Espero que estas funciones puedan ayudar a toda la comunidad.

Un saludo.


La franja horaria es GMT +2. Ahora son las 19:35:16.

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