Page 1 of 1

Reuse an Instance of TVirtualQuery

Posted: Wed 23 Aug 2017 17:03
by Aggie85
Howdy All!

I have for the most part successfully converted my large ~14 year program from TxQuery to TVirtualQuery (over 4500+ instances).

For the most part, my implementation of TVirtualQuery ALWAYS recreates the TVirtualQuery object. I have a few modules in my product where after so many recreations of TVirtualQuery, I get an EAccessError.

I have tried implementing a simple cleanup procedure to reuse an instance of a TVirtualQuery and it never works.

The procedure is as follows:

1) Make sure instance of TVirtualQuery is inactive.
2) Clear the previous Source Data Sets.
3) Add new source data sets.
4) Attempt reuse.

Step #4 always tells me my new source datasets don't exist.

What am I missing?

All the best,

Aggie85

Re: Reuse an Instance of TVirtualQuery

Posted: Mon 28 Aug 2017 08:51
by MaximG
Thank you for the information. Please describe the specified situation in more detail. For this, compose and send us a small sample, which when executed causes the EAccessError error. You can send this sample using the e-support form(https://www.devart.com - the "Support"\"Request Support" menu)

Re: Reuse an Instance of TVirtualQuery

Posted: Fri 01 Sep 2017 16:56
by Aggie85
Howdy Maxim!

The EAccessError is only caused after a lot of resets and it may/may not be caused by TVirtualQuery.

Back to my original question, could you please tell me how to reuse an instance of a TVirtualQuery to execute a NEW SQL statement with new SourceDataSets? The only way I have found to work is to delete previous instance of TVirtualQuery and recreate it (new).

Have a great weekend,

Aggie85

Re: Reuse an Instance of TVirtualQuery

Posted: Wed 06 Sep 2017 14:06
by MaximG
The sample of deleting and recreating SourceDataSets when using VirtualQuery :

Code: Select all

program VQC;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils, Data.DB, DBAccess, DBClient, VirtualQuery;

var
 DataSet1, DataSet2: TClientDataSet;
 VirtualQuery: TVirtualQuery;
begin
  DataSet1 := TClientDataSet.Create(Nil);
  DataSet2 := TClientDataSet.Create(Nil);
  try
    DataSet1.FieldDefs.Add('DeptNo', ftInteger);
    DataSet1.FieldDefs.Add('DName', ftString, 64);
    DataSet1.CreateDataSet;
    DataSet1.Open;
    DataSet1.AppendRecord([10, 'ACCOUNTING']);
    DataSet1.AppendRecord([20, 'SALES']);
    DataSet2.FieldDefs.Add('EmpNo', ftInteger);
    DataSet2.FieldDefs.Add('DeptNo', ftInteger);
    DataSet2.FieldDefs.Add('EName', ftString, 64);
    DataSet2.CreateDataSet;
    DataSet2.Open;
    DataSet2.AppendRecord([1, 10, 'JONES']);
    DataSet2.AppendRecord([2, 10, 'MARTIN']);
    DataSet2.AppendRecord([3, 20, 'SMITH']);

    VirtualQuery := TVirtualQuery.Create(Nil);
    try
      VirtualQuery.SourceDataSets.Add(DataSet1, '', 'Table1');
      VirtualQuery.SQL.Text := 'Select * From Table1';
      VirtualQuery.Open;
      VirtualQuery.SourceDataSets.Clear;
      VirtualQuery.SourceDataSets.Add(DataSet2, '', 'Table2');
      VirtualQuery.SQL.Text := 'Select * From Table2';
      VirtualQuery.Open;
    finally
      VirtualQuery.Free;
    end;

  finally
    DataSet1.Free;
    DataSet2.Free;
  end;
end.


Re: Reuse an Instance of TVirtualQuery

Posted: Wed 06 Sep 2017 16:19
by Aggie85
Howdy Maxim!

I will need to put together a small example as I was doing what your small example showed.

The only difference is I was performing an Update on a table in the first SQL statement and then a DELETE on the second table. The second statement is where I get the unknown table message.

Thanks,

Aggie85