Autor Téma: Blob - read/write z Firebirdu cez FireDAC  (Přečteno 127 krát)

Offline František

  • Hrdina
  • ****
  • Příspěvků: 340
  • Karma: 4
    • Verze Delphi: primárne v XE5, občaas 10.1 starter, XE, BDS2006
Blob - read/write z Firebirdu cez FireDAC
« kdy: 12-06-2018, 22:35:49 »
takto čítam
Kód: [Vybrat]
  function GetBlobText(SQLQ:TFDQuery; bField:string ):string;
  var
    bs: TMemoryStream;
    sl: TStringList;
  begin
    sl := TStringList.Create;
    bs := TMemoryStream.Create;
    try
      TBlobField(SQLQ.FieldByName(bField)).SaveToStream(bs);
      bs.Position := 0;
      if bs.Size > 0
        then begin
                sl.LoadFromStream(bs);
                result := sl.Text;
        end
        else result := '';

    finally
      bS.Free;
      sl.Free;
    end;
  end;

a takto zapisujem
Kód: [Vybrat]
procedure SetBlobText(trQuery:TFDQuery; text:string );
var
    msp: TMemoryStream;
    pSL: TStringList;
    trQuery: TFDQuery;
begin
        msp := TMemoryStream.Create();
        pSL := TStringList.create;
        pSL.Text := text;
        pSL.SaveToStream(msp);
        try
          trQuery.sql.DefaultEncoding := System.SysUtils.TEncoding.UTF8;
          trQuery.SQL.Clear;
          trQuery.SQL.Add('UPDATE XXX SET ');
          trQuery.SQL.Add('POZITIV = :POZITIV ');
          trQuery.SQL.Add('WHERE IDT = 1');
          trQuery.ParamByName('POZITIV').SetBlobRawData(msp.Size,msp.Memory);
          trQuery.ExecSQL;
        finally
             pSL.Free;
             msp.Free;
        end;
end;
v podstate to funguje, ale bol som upozornený, že existuje niečo elegantnejšie
(pre XE5)
ak máte nejaké vylepšenie, sem s ním,
vďaka aj za iných

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 863
  • Karma: 42
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:Blob - read/write z Firebirdu cez FireDAC
« Odpověď #1 kdy: 12-06-2018, 23:24:07 »
Predpokladejme tedy, ze se jedna o definici sloupce BLOB SUB_TYPE TEXT (proc taky jinak vracet z podobnych funkci retezec typu string). Nevim jak Delphi XE5, nicmene FireDAC v Delphi Tokyo umi primy pristup k BLOB datum Firebird typu BLOB SUB_TYPE TEXT pomoci AsString accessoru (a to jak pro pole tak parametry, tedy cteni i zapis).
« Poslední změna: 12-06-2018, 23:46:17 od Delfin »
I'm a soldier, so don't panic!

Offline KarelHorky

  • Plnoletý
  • ***
  • Příspěvků: 165
  • Karma: 6
    • Verze Delphi: 7, XE6
Re:Blob - read/write z Firebirdu cez FireDAC
« Odpověď #2 kdy: 13-06-2018, 08:05:47 »
Toto teď používám k plné spokojenosti v XE6, v XE5 to snad pojede taky. Přenáším obsah blobu z jedné tabulky do jiné tabulky:
Kód: Delphi [Vybrat]
  1. var
  2.   Pozn: TStream;
  3.  
  4. if not FDQuery1.FieldByName('PAR_BLOB').IsNull then
  5. begin
  6.   Pozn := FDQuery1.CreateBlobStream(FDQuery1.FieldByName('PAR_BLOB'), bmRead);
  7.   Pozn.Position := 0;
  8.   FDQuery2.ParamByName('BLOB_CIL').LoadFromStream(Pozn, ftBlob);
  9.   Pozn.Free;
  10. end;
  11.  

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 863
  • Karma: 42
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:Blob - read/write z Firebirdu cez FireDAC
« Odpověď #3 kdy: 13-06-2018, 13:44:55 »
Toto teď používám k plné spokojenosti v XE6, v XE5 to snad pojede taky. Přenáším obsah blobu z jedné tabulky do jiné tabulky:
Kód: Delphi [Vybrat]
  1. var
  2.   Pozn: TStream;
  3.  
  4. if not FDQuery1.FieldByName('PAR_BLOB').IsNull then
  5. begin
  6.   Pozn := FDQuery1.CreateBlobStream(FDQuery1.FieldByName('PAR_BLOB'), bmRead);
  7.   Pozn.Position := 0;
  8.   FDQuery2.ParamByName('BLOB_CIL').LoadFromStream(Pozn, ftBlob);
  9.   Pozn.Free;
  10. end;
  11.  

I vyse citovane bude fungovat protoze nakonec stejne dojde k implicitni konverzi metodou TFDFormatOptions.ConvertRawData.

Porad vsak predpokladam definici sloupce BLOB SUB_TYPE TEXT a pro nej je nejcistejsi nejspis tohle (nedochazi k zadne konverzi); pro ANSI sloupec:

Kód: Delphi [Vybrat]
  1. FDQuery2.ParamByName('ParamAnsiBlobText').AsMemo := TMemoField(FDQuery1.FieldByName('FieldAnsiBlobText')).Value;

Pro Unicode sloupec pak podobne:

Kód: Delphi [Vybrat]
  1. FDQuery2.ParamByName('ParamUnicodeBlobText').AsWideMemo := TWideMemoField(FDQuery1.FieldByName('FieldUnicodeBlobText')).Value;

AsString accessor bude fungovat taky, jen dojde k implicitni konverzi. Ten meziclanek se streamy si totiz koleduje o chybu v kodovani (pri pouhem binarnim prenosu dat to vsak nevadi, o zbytek se totiz postara FireDAC).
« Poslední změna: 13-06-2018, 14:11:34 od Delfin »
I'm a soldier, so don't panic!

 

S rychlou odpovědí můžete používat BB kódy a emotikony jako v běžném okně pro odpověď, ale daleko rychleji.

Jméno: E-mail:
Ověření:
Kolik je šest plus čtyři (slovem):