Newsgroup: it.comp.lang.delphi
Titolo: Blob su MySql

Ho un fastidioso problema con Firedac + MySql su Delphi 10.3
Tabella test con 3 campi
* Id autoincrement
* immagine BLOB
* immagine1 TINYBLOB
 
da MySqlWordkBench riesco ad inserire l'immagine sia sul Blob che sul 
TinyBlob (dimensione 73kb)
 
- da Codice ricevo errore : [Firedac][Phys][MySql] data too long for 
column immagine at row 1
 
procedure Tfrm_Articoli.InserisceImmagine(sFile: string);
var fStream: TFileStream;
begin
 
  FDQuery1.Close;
  fStream := TFileStream.Create(sFile, fmOpenRead or fmShareDenyNone);
 
  //fStream.size = 73813 byte
 
  FDQuery1.SQL.Text := 'INSERT INTO tb_test (immagine1) VALUES (:img)';
  FDQuery1.ParamByName('img').LoadFromStream(fStream, ftBlob);
  FDQuery1.ExecSQL;
 
//...
end;
 
Se ne capite piu' di me, provate a darmi qualche suggerimento, anche con 
il classico Edit/Post.

Il 22/07/2019 14:12, Maurizio ha scritto:
 
Risolto (quasi, ancora un problema con file da 5 Mb - es: 4.987.904 
dovrebbe andare senza intoppi su MEDIUMBLOB invece
Lost Connection during query... da capire, gia' con file da 2,7 Mb si
verifica).
 
in MySql
{
TINYBLOB   :     maximum length of 255 bytes
BLOB       :     maximum length of 65,535 bytes
MEDIUMBLOB :     maximum length of 16,777,215 bytes
LONGBLOB   :     maximum length of 4,294,967,295 bytes
}
 
procedure Tfrm_Articoli.InserisceImmagine(sFile: string);
var jp:TJpegImage;
     MemStream: TMemoryStream;
begin
   sFile := '<foto da inserire>';
 
   FDQuery1.Open;
   FDTransaction1.StartTransaction;
 
   //Medium Blob
   sFile := '<foto da inserire>';
 
   FDTransaction1.StartTransaction;
 
   try
     jp := TJpegImage.Create;
     jp.LoadFromFile(sFile);
     FDQuery1.Active := true;
     FDQuery1.Insert;
     FDQuery1.FieldByName('immagine1').Assign(jp);
     FDQuery1.Post;
     FreeAndNil(jp);
     FDTransaction1.Commit;
   except
     FDTransaction1.RollBack;
   end;
 
//versione SQL
 
   MemStream := TMemoryStream.Create;
 
   sFile := '<foto da inserire>';
   Image1.Picture.LoadFromFile(sFile);
 
   Image1.Picture.SaveToStream(MemStream);
   MemStream.Seek(0,0);
   FDQuery1.SQL.Text := 'INSERT INTO tb_test (immagine1) VALUES (:img)';
   FDQuery1.ParamByName('img').LoadFromStream(MemStream, ftBlob);
   FDQuery1.ExecSQL;
 
..//
end;


Ciao Maurizio,
  uso firedac con diverse versioni di delphi (dalla seattle in poi) e con i 
blob non ho avuto grossi problemi.
Per inserire non uso sql ma la vecchia  tabella e la procedura con cui salvo 
i blob e' la seguente
 
Tabella.FieldByName('CampoBlob') as 
TBlobField).LoadFromFile(Foto_da_salvare);
 
Per una serie di considerazioni personali tendo ad usare sql solo per le 
interrogazioni, per inserimenti o modifiche uso ancora le tabelle (comunque 
presenti in FireDac).
 
Ciao
 
Daniele 
 

Il 22/07/2019 14:12, Maurizio ha scritto:

Prima di usare un .load.. o un .save di un qualche tipo di stream 
ricordo che li precedevo da fStream.position:=0 che posiziona il 
puntatore all'inizio dello stream.
 
http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/Classes_TStream_Position.html
 
-- 
 


Esatto.
Entrambi fanno si che la posizione del flusso sia impostata su x. La differenza sta nel fatto che il metodo "position" elimina incondizionatamente qualsiasi buffer di lettura, mentre il metodo "seek" tenta di conservare la parte del buffer che è ancora rilevante per la nuova posizione.
Nel caso specifico rimane corretto position.