1

My Delphi 10.4.2 project stores the contents of a .WAV file in a SQLite3 database blob field with this code:

fSQLite3Query: TFDQuery;

fSQLite3Query.ParamByName(kSQLFieldMultimediaFileContents).LoadFromFile(MultimediaFileName, ftBlob);

After a successful SELECT * query, what code is used to save the contents of that field back into a file?

Mike at Bookup
  • 1,211
  • 14
  • 32
  • 1
    `Params` only apply to the query, not the resultset. For that, you use `FieldByName` and the field (column) name that is in the table or an alias you used in your query, or a persistent field you defined (see MartynA's answer for more info on them). You can find an example of working with TBlobField [here](https://stackoverflow.com/a/11775398/62576) - just replace the ADOQuery with your FDQuery. – Ken White Apr 15 '21 at 18:46
  • Thanks, @KenWhite, both good points. – MartynA Apr 15 '21 at 18:57
  • 1
    Thanks @KenWhite. From your link regarding TBlobField I got this code to work: theBlobField := TBlobField(fSQLite3Query.FieldByName(kSQLFieldMultimediaFileContents)); theBlobField.SaveToFile(MultimediaFileName); – Mike at Bookup Apr 15 '21 at 22:15

1 Answers1

3

You could use TBlobField's SaveToFile to do this. Obviously this is simplest if you set up persistent TFields, including a TBlobField on the relevant field, in the Delphi IDE.

See http://docwiki.embarcadero.com/Libraries/Sydney/en/Data.DB.TBlobField.SaveToStream

MyBlobField.SaveToFile('c:\temp\somewavfile.wav');

Update I gather from your comment that you are having trouble relating what I said to your code, so I'll try and explain this as clearly as I can.

When you open an FDQuery with a Sql query, unless you take steps for the FDQuery to behave differently, it will create one TField-descendant field per column in the Sql's result-set. FireDAC uses metadata from the server to determine which TField descendant (e.g. TIntegerField, TStringField, TBlobField) it creates for each Sql column. The FDQuery will free the fields as sooon as you call .Close() on the FDQuery.

An alternative way of working is to create "persistent" Fields, which continue to exist even when the FDQuery is closed. The main reason to do this is so that you know at design-time what type of TField-descendant is used for each column of the result set and set certain behaviours (like the display format of the fields). To set up persistent TFields, what you can do is this:

  • In the IDE, right-click on the FDQuery, and click on the Fields editor... in the pop-up.
  • Then, you will get the Fields editor pop-up.
  • Right-click on that and select Add all fields from the context menu.
  • The Fields editor will then populate with one field for each column in the Sql result-set. (At this point you can also manually add calculated and lookup fields if you want to).

Once all that is done, you'll find that the fields show up in the object Inspector, each with a component name which is based on a combination of the FDQuery's name and the related column name of the Sql query. Hopefully, for your column that contains the .WAV files, the field type will be a MemoField. If it is, you're home and dry; if it's not, right-click in the Fields editor, make a note of the WAV data FieldName, delete the WAV data column and right click to manually create a TMemoField and set its FieldName property to the named you just noted.

Then you can used SaveToFile on the MemoField you've just created.

MartynA
  • 30,454
  • 4
  • 32
  • 73
  • I have looked at the documentation as thoroughly as I can. I have no idea how to get from fSQLite3Query to "using TBlobfield's SaveToFile()" The word "obviously" is lost on me. :) – Mike at Bookup Apr 15 '21 at 15:29
  • 1
    No probs - see the update i've just posted. – MartynA Apr 15 '21 at 16:11
  • I've learned a lot from this answer. I had no idea that an FDQuery was a visual component that could be edited in the Delphi IDE. I was creating the TFDQuery in code. The key line of code I did not realize I would need is this one: theBlobField := TBlobField(fSQLite3Query.FieldByName(kSQLFieldMultimediaFileContents)); – Mike at Bookup Apr 15 '21 at 22:20