Newsgroup: it.comp.lang.delphi
Titolo: Firedac Blob su Query Insert

componente FDQuery su XE7
 
//inizializzazione crea Sql di inserimento
   FDQuery1.Close;
   FDQuery1.SQL.Text := 'INSERT INTO TB_IMMAGINI (ID, DATA, DIMENSIONE, 
NOMEFILE, IMMAGINE) ' + 'VALUES (:ID, :DATA, :DIMENSIONE, :NOMEFILE, 
:IMMAGINE)';
 
//crea i parametri : ptInput - assegnero' un valore in seguito
   FDQuery1.Params.Clear;
   FDQuery1.Params.CreateParam(ftInteger,'ID', ptInput);
   FDQuery1.Params.CreateParam(ftDate,'DATA', ptInput);
   FDQuery1.Params.CreateParam(ftInteger,'DIMENSIONE', ptInput);
   FDQuery1.Params.CreateParam(ftString,'NOMEFILE', ptInput);
   FDQuery1.Params.CreateParam(ftBlob,'IMMAGINE', ptInput);  //parametro 
Blob
 
.... routine di inserimento, riceve MemStream valorizzato
procedure Tfrm_DatiImmagini.InserisceImmagine(MemStream: TMemoryStream; 
sFile: string; bScriviImg: boolean);
 
//esegue la Query ... tutti i valori vanno bene ....
      FDQuery1.ParamByName('ID').Value := Get_ID;
      FDQuery1.ParamByName('DATA').Value := dData;
      FDQuery1.ParamByName('DIMENSIONE').Value := MemStream.Size;
      FDQuery1.ParamByName('NOMEFILE').Value := sFile;
 
---> non  mi spiego perche' non riesce a caricare lo stream ... access 
violation
 
      FDQuery1.ParamByName('IMMAGINE').LoadFromStream(MemStream, 
ftBlob);    ... tranne questo ...
      FDQuery1.ExecSQL;
 
 
una normale procedure Insert/Post  non crea problemi
 
FDQuery.Insert;
....
(FDQuery1.FieldByName('IMMAGINE') as TBlobField).LoadFromStream(MemStream);
...
FDQuery1.Post;

 FDQuery1.ParamByName('IMMAGINE').LoadFromStream(MemStream, ftBlob);    
 
Non ho ancora avuto il (dis)piacere di usare i blob con firedac...
 
0) verificare se ci sono giri particolari da fare per i parametri blob con firedac. Il "dove" vedere è scontato, no?
 
1) dichiara una variabile alla quale assegni  FDQuery1.ParamByName('IMMAGINE')
Magari per qualche motivo non trova il parametro e zompa 
 
2) verifica la position dello stream.
Magari non è zero e quando l'assegnazione tenta di leggerlo becca una condizione tipo "eof!" e zompa
 
3) non hai indicato quale database stai usando.
Magari il db non ti permette un modo diretto di fare questa cosa?
Ricordo che con d7+ado+oracle 1o e 11, usando OLEDB provider di Oracle ho avuto dei casini nel fare una cosa simile con uno stream superiore ad una dimensione che purtroppo ora non ricordo.
Magari prova con uno stream di 10 bytes e vedi cosa succede.
 
 
A.

 >>> //crea i parametri : ptInput - assegnero' un valore in seguito
 >>>     FDQuery1.Params.Clear;
 >>>     FDQuery1.Params.CreateParam(ftInteger,'ID', ptInput);
 >>
 >> Se non erro, una volta assegnato lo statement sql, un prepare 
dell'oggetto dovrebbe popolarti la collection
[..]
 
lo verifico, ma forzando l'assegnazione , non puo' cambiare risultato
 
 >>
 >>> procedure Tfrm_DatiImmagini.InserisceImmagine(MemStream: TMemoryStream;
 >>> sFile: string; bScriviImg: boolean);
 >>
 >>
 >> Ti suggerisco di indicare SEMPRE i qualificatori const e var per i 
parametri che non siano pointer, riferimenti ad oggeti etc.
 >>
 >>
 >>> FDQuery1.ParamByName('IMMAGINE').LoadFromStream(MemStream, ftBlob);
 >>
 >> Non ho ancora avuto il (dis)piacere di usare i blob con firedac...
 >>
 >> 0) verificare se ci sono giri particolari da fare per i parametri 
blob con firedac. Il "dove" vedere è scontato, no?
 
ho fatto di meglio
http://docs.embarcadero.com/products/rad_studio/firedac/frames.html
 
 
 >>
 >> 1) dichiara una variabile alla quale assegni 
FDQuery1.ParamByName('IMMAGINE')
 >> Magari per qualche motivo non trova il parametro e zompa
 
il parametro MemStream, FSize, FPosition hanno un valore
 
 >>
 >> 2) verifica la position dello stream.
 
Position =  0
 
 >> Magari non è zero e quando l'assegnazione tenta di leggerlo becca 
una condizione tipo "eof!" e zompa
 >>
 >> 3) non hai indicato quale database stai usando.
 >> Magari il db non ti permette un modo diretto di fare questa cosa?
 
FB 2.5 , il db lo permette, stesso Db e Tabella con ZeosLib accetta la 
stesso stream (stessi valori)
 
 >> Ricordo che con d7+ado+oracle 1o e 11, usando OLEDB provider di 
Oracle ho avuto dei casini nel fare una cosa simile con
[..]
 
 
avevo gia' provato, assegnando Size := 1
 

 stesso stream (stessi valori)
 
IO ODIO ZEOSLIB.
 
A.
 
 
 
 

Sinceramente per i Blob uso sempre l'SQL che funziona "quasi" sempre, 
per esempio cosi'
 
Var
  Stream : TFileStream;
 
Begin
   Stream := TFileStream.Create(Nome_File, fmOpenRead);
   try
    MainQuery.SQL.Clear;
 
    MainQuery.SQL.Add('INSERT INTO Tabella1 (MyBlob)');
 
    MainQuery.SQL.Add('VALUES (:IMGBlob);');
 
    MainQuery.ParamsSetBlob('IMGBlob', Stream);
 
    MainQuery.Execute;
 
    Transazione.CommitRetaining;
 
   finally
     Stream.Free;
   end;