Oleksandr
Oleksandr

Reputation: 21

EOutOfMemory when open TFDQuery for one record

  1. When I try to get one record from a table I get an error. I use TFDQuery (select SLDDATA, SLDTIME from TSYSLOGDATA WHERE SLDTIME = '2019-12-11 00:00:00.000')

    exception class : EOutOfMemory main thread ($6a28): 00bfaeda +066 TDAdmin.exe FireDAC.Phys.ODBCWrapper 3752 +13 TODBCVariable.AllocLongData 00bff3f8 +1a8 TDAdmin.exe FireDAC.Phys.ODBCWrapper 5178 +51 TODBCStatementBase.GetLongVar 00bff52b +06b TDAdmin.exe FireDAC.Phys.ODBCWrapper 5225 +10 TODBCStatementBase.FetchLateBindedColumns 00bff63b +0ff TDAdmin.exe FireDAC.Phys.ODBCWrapper 5266 +29 TODBCStatementBase.Fetch 00c09ffa +05a TDAdmin.exe FireDAC.Phys.ODBCBase 2996 +7 TFDPhysODBCCommand.InternalFetchRowSet 00be8742 +066 TDAdmin.exe FireDAC.Phys 8669 +8 DoFetch

Database is on MS SQL Server. The table has two columns SldDate DateTime and SldData Nvarchar(max). No primary key. SldData contains 422971068 bytes string. As I investigated this long string is a reason of the issue.

Any ideas how to resolve this?

  1. I got the same error for 211485518 bytes string.

  2. I got an access violation when I tried to used a parameter

    FDQuery1.SQL.Text := 'SELECT :SYSLOGDATA = SLDDATA FROM TSYSLOGDATA WHERE SLDTIME = ''2019-12-15 00:00:00.000'''; with FDQuery1.Params[0] do begin DataType := ftWideMemo; ParamType := ptOutput; end; FDQuery1.Command.CommandKind := skExecute; FDQuery1.ExecSQL;

Project Project1.exe raised exception class $C0000005 with message 'access violation at 0x004075bf: write of address 0x6b3b0000'.

System.Move(???,???,???)
:004075bf Move + $77
FireDAC.Phys.ODBCBase.ProcessArrayItem(???,???,0,???)
FireDAC.Phys.ODBCBase.TFDPhysODBCCommand.GetParamValues(???,0,-1)
FireDAC.Phys.ODBCBase.TFDPhysODBCCommand.InternalExecute(1,0,???)
FireDAC.Phys.Process_HandleSystemFailure(1,0,-1,False)
FireDAC.Phys.Process_SingleRow
FireDAC.Phys.TFDPhysCommand.ExecuteBase(1,0)
FireDAC.Phys.TFDPhysCommandAsyncExecute.Execute
FireDAC.Stan.Async.TFDStanAsyncExecutor.ExecuteOperation(False)
FireDAC.Stan.Async.TFDStanAsyncExecutor.Run FireDAC.Phys.TFDPhysCommand.ExecuteTask(TFDPhysCommandAsyncExecute($2A8BDF8) as IFDStanAsyncOperation,TFDCommand($29904D0) as IFDStanAsyncHandler,False)
FireDAC.Phys.TFDPhysCommand.Execute(???,???,False)
FireDAC.Comp.Client.TFDCustomCommand.InternalExecute(0,0,False)
FireDAC.Comp.Client.TFDCustomCommand.Execute(0,0,False)
FireDAC.Comp.Client.TFDAdaptedDataSet.DoExecuteSource(0,0)
FireDAC.Comp.DataSet.TFDDataSet.Execute(0,0)
FireDAC.Comp.Client.TFDCustomQuery.ExecSQL
  1. I tried to get data by chunks like this. I run first sql script. Got data and put to local variable. And I got the same error EOutOfMemory on the second sql script when I tried to get data from the field (FDQuery1.Fields[1].AsString)

SELECT SUBSTRING(SLDDATA, 1, 100000000) SLDDATA, SLDTIME FROM TSYSLOGDATA SELECT SUBSTRING(SLDDATA, 100000001, 200000000) SLDDATA, SLDTIME FROM TSYSLOGDATA

Upvotes: 2

Views: 487

Answers (1)

da-soft
da-soft

Reputation: 7750

You should try to use Blob Streaming: http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Support_for_Blob_Streaming_in_FireDAC Quote from above:

The client side memory usage is minimized, comparing to the "by value" requirement for additional memory usage equal to 3-4 time of the BLOB value size;

Upvotes: 0

Related Questions