Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Firebird e Interbase (https://www.clubdelphi.com/foros/forumdisplay.php?f=19)
-   -   Concatenación de campos BLOB (https://www.clubdelphi.com/foros/showthread.php?t=93598)

santiago14 26-11-2018 14:05:04

Concatenación de campos BLOB
 
Buenas, estoy trabajando con Firebird 3.0, Delphi XE5, FireDac.
Necesito concatenar dos campos BLOB, lo que hago es lo siguiente:

Código SQL [-]
Select a.titulo_aviso_admin || a.cuerpo_aviso_admin AS titulo_aviso
From sumario_Admin s 
-- ...

Pero cuando ejecuto, solamente me devuelve lo que está en a.titulo_aviso_admin, sin concatenación con la segunda parte.
Aclaro que, lo que hay en los campos está en formato RTF, pero al menos debería mostrarme que los junta, o un error. Sin embargo, lo hace pero no concatena.
Bueno, espero haber sido claro.
Ojalá puedan ayudarme.

Gracias.
Santiago.

fjcg02 27-11-2018 22:51:00

Hola,
aunque no tengo ninguna certeza, supongo que los tiros van por la concatenación.

Al concatenar, el segundo blob tiene la cadena de comienzo de fichero. Supongo que por eso se te china.

Quítale un cacho de x caracteres al principio del segundo blob, concatena y prueba.

Saludos

Casimiro Notevi 28-11-2018 02:20:22

Si los campos son blob binario (subtipo 0) no podrás, tendrás que extraerlos.
Pero si los campos son blob de texto (subtipo 1) sí que podrás concatenarlos normalmente con ||


ecfisa 28-11-2018 04:37:54

Hola.

Tratándose de la versión 3 de Firebird no me aventuro a asegurarlo por que desconozco sus cambios, pero la versión 2.5 se comporta de igual modo.

Leyendo en The Firebird Book de Helen Borrie encontré :
Cita:

Operations on BLOBs

A BLOB is never updated. Every update that “changes” a BLOB causes a new BLOB to
be constructed, complete with a new BLOB ID. The original BLOB becomes obsolete
once the update is committed.

A BLOB column can be tested for NULL/NOT NULL, but no internal function
exists to compare one BLOB with another or to compare a BLOB to a string. Several
BLOB UDFs are available from community download sites, including some that compare
two BLOBs for equality.

It is not possible to concatenate two BLOBs or to concatenate a string to a BLOB.
...
(Cap. 12 - pg. 184)
También encontré mención a esto en otros enlaces como por ejemplo en: BLOB Types Firebird

Intentando otro camino, no sería mayor problema hacerlo desde Delphi mediante Streams si no se tratase de contenido con formato RTF. Pero, lamentablemente ese formato posee cabecera, finalizacion, etc. y no se puede concatenar como si se tratase de texto o contenido binario.

Finalmente, como te comenta Antonio usando SUB_TYPE 1 sí que Firebird lo puede hacer sin problemas, pero estarías trabajando con texto sin formato.

Saludos :)

santiago14 28-11-2018 16:18:36

Entiendo.
Tienen razón, no hay manera de concatenar si son RTF. Hay que extraerlos y hacerlo con Stream's.
Ya estoy en eso.

Pongo a consideración unos pequeños procedimientos que hacen eso. Espero sirva. Los hice en DelphiXE5.

Código Delphi [-]
{-------------------------------------------------------------------------------
  Procedure: RichEditToPlainText
  Author:    santiago
  DateTime:  2018.11.27
  Arguments: RichEdit:TRichEdit
  Result:    string
  Comments: Tomamos un RichEdit y lo ponemos en texto plano.
-------------------------------------------------------------------------------}
function RichEditToPlainText(RichEdit:TRichEdit):string; overload;
var
  Stream:TStream;
  ed: TRichEdit;
begin
  ed:=TRichEdit.CreateParented(HWND_MESSAGE);
  Stream:=TStream.Create;
  ed.PlainText:=True;
  RichEdit.Lines.SaveToStream(Stream);
  ed.Lines.LoadFromStream(Stream);
  Result:=Trim(ed.Lines.Text);
  ed.Free;
  Stream.Free;
end;

function RichEditToPlainText(Stream:TStream):string; overload;
var
  ed: TRichEdit;
begin
  ed:=TRichEdit.CreateParented(HWND_MESSAGE);
  ed.PlainText:=True;
  ed.Lines.LoadFromStream(Stream);
  Result:=Trim(ed.Lines.Text);
  ed.Free;
end;

Muchas gracias.

santiago14 28-11-2018 16:31:09

Para que se entienda, esto los pone a todos en Texto Plano. Luego, podemos hacer con ellos lo que nos plazca.

Santiago.

ecfisa 28-11-2018 21:54:29

Hola.

Como comentaste que necesitabas concatenar dos campos Blob, te pongo una alternativa que prescinde del uso de TRichEdit para la conversión:

Código Delphi [-]
function ConcatBlob(Field1, Field2: TField): string;
var
  s1, s2: TStringStream;
  a, b: string;
begin
  // Field1
  s1 := TStringStream.Create('');
  try
    TBlobField(Field1).SaveToStream(s1);
    a := s1.DataString;
    SetLength(a, Length(a)-SizeOf(DWORD));
  finally
    s1.Free;
  end;

  // Field2
  s2 := TStringStream.Create('');
  try
    TBlobField(Field2).SaveToStream(s2);
    b := s2.DataString;
  finally
    s2.Free;
  end;
  Result := a + b;
end;

Ejemplo de uso:
Código Delphi [-]
procedure TForm1.btConcatClick(Sender: TObject);
var
  cad: string;
begin
  cad := ConcatBlob(DataSet.FieldByName('BLOB_1'), DataSet.FieldByName('BLOB_2'));
  RichEdit3.Text := cad;
end;

Resultado:


Saludos :)

santiago14 28-11-2018 22:14:05

Uuuuuh. Me parece genial.
Lo voy a probar y veo como queda. Pero creo que es el camino.
Gracias.


La franja horaria es GMT +2. Ahora son las 21:22:05.

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