Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Refreshing the dataset of a provider

146 views
Skip to first unread message

Natalie Boodram

unread,
Apr 6, 1999, 3:00:00 AM4/6/99
to
Hi,

I have a 3-tier app that has a provider linked to a TQuery on the server
side. On the client side I have a client dataset hooked up to the provider.
If I add a new record to my client dataset and apply updates, all is fine.
If I close my client dataset and reopen it, I do not see the new record. It
is as if the TQuery does not re-execute itself. Is there a way I can
explicitly open and close the TQuery when my client dataset opens and
closes? Is there a better way of doing this? Does this mean that any
providers/queries on my application server that I have opened one the client
app has been started will stay open and in memory until the client closes
(unless I explicitly close them)?

Thanks,
Natalie

Natalie Boodram

unread,
Apr 6, 1999, 3:00:00 AM4/6/99
to
One more piece of information: If I run the application server locally (on
the same machine as the client) this refresh problem does not occur.

Natalie


Natalie Boodram wrote in message <7ed513$q6...@forums.borland.com>...

Aldis Viesturs

unread,
Apr 6, 1999, 3:00:00 AM4/6/99
to
TClientDataSet onlu simulate, that its closed. Actualy all data stays in clients
memory. try the following(after applyUpdates): ClientDataSet.Data:=null;

Alex Karpenko

unread,
Apr 6, 1999, 3:00:00 AM4/6/99
to borland.public.delphi.database.multi-tier
Hi Natalie,
I've just faced the same problem. I'm not sure if it's absolutely correct
but there's the thing I found. There're two ways to apply updates.

The fisrt: you make the TPovider to apply updates for you. In this case you
should do just nothing. Make sure if TPovider.ResolveToDataSet is False.
Then as far as I understood TProvider just uses the list of fields of you
TQuery to generate queries for updating and doesn't applies the updates to
TQuery, but directly to database.

The second: if you want to control applying updates personally, then you
must use TDataSetProvider instead of TProvider (by the way I suspect that it
must be the same as TProvider.ResolveToDataSet = True, but I met some
troubles when using it and not sure) and write some code on
TDataSetProvider.OnUpdateData, OnBeforeUpdateRecord or OnAfterUpdateRecord
events.
For example I did this like that:

procedure TRemoteDataModule.Query1UpdateRecord(DataSet: TDataSet;
UpdateKind: TUpdateKind; var UpdateAction: TUpdateAction);
begin
Query1.Apply(UpdateKind);
UpdateAction:= uaApplied;
end;

procedure TRemoteDataModule.DataSetProvider1DataAfterUpdateRecord(Sender:
TObject; SourceDS: TDataSet; DeltaDS: TClientDataSet; UpdateKind:
TUpdateKind);
begin
{ // it works but in fact the updates are being applied when the RDM is
being destroyed
with SourceDS as TQuery do
begin
ApplyUpdates;
CommitUpdates;
end;}
// this works fine, updates are being applied at once
DataBase.ApplyUpdates([SourceDS as TQuery]);
end;

I use TUpdateSQL with TQuery as well as Delphi 4 SP 3
I don't know, maybe Dan Miser will be upset because of my advice :) but I'm
new to MIDAS

Natalie Boodram

unread,
Apr 6, 1999, 3:00:00 AM4/6/99
to
I tried this and it does not fix the problem. The problem does not seem to
be that the client dataset is hanging on to old data, but rather the server
hanging on to old data. Can anyone tell me where is the appropriate place to
open and close the query linked to the provider, and if this is what I
should be doing?
Natalie

Aldis Viesturs wrote in message <370A321B...@isc.ldz.lv>...

Dan Miser [TeamB]

unread,
Apr 6, 1999, 3:00:00 AM4/6/99
to
In article <SFTL16...@softline.kiev.ua>, Alex Karpenko wrote:
> The second: if you want to control applying updates personally, then you
> must use TDataSetProvider instead of TProvider (by the way I suspect that it
> must be the same as TProvider.ResolveToDataSet = True, but I met some
> troubles when using it and not sure) and write some code on
> TDataSetProvider.OnUpdateData, OnBeforeUpdateRecord or OnAfterUpdateRecord
> events.
> For example I did this like that:
>
You don't have to use TDatasetProvider to have control of your updates. You
can still use TProvider.

The ResolveToDataset option means that MIDAS will attempt to resolve the
changes to the DB using standard Delphi database techniques, i.e. by using the
BDE. You do get to use some of the TDBDataset events this way, but it is much
slower than the native MIDAS resolving method.

> I use TUpdateSQL with TQuery as well as Delphi 4 SP 3
> I don't know, maybe Dan Miser will be upset because of my advice :) but I'm
> new to MIDAS
>

Maybe... <g> If you're using TUpdateSQL as a place-holder for your queries, I
find that to be a very good use of the component in MIDAS. Using it with
CachedUpdates that you apply yourself to a MIDAS application is redundant. Why
use CachedUpdates on the server? You don't want updates cached there.
--
Dan Miser
http://www.execpc.com/~dmiser
(TeamB cannot answer questions received via EMail)


Dan Miser [TeamB]

unread,
Apr 6, 1999, 3:00:00 AM4/6/99
to
Make sure your query is closed at design-time. In general, don't touch
any TDBDataset.Active properties (or TDatabase.Connected) of any
TDBDataset that MIDAS uses.

Alexis Rodriguez

unread,
Apr 6, 1999, 3:00:00 AM4/6/99
to
Natalie,
If you close ClientDataSet and FProvider is nil Data is saved in internal
cache, and when you Open data is load from cache.
TCustomRemoteServer.Connected := false set all FProvider set to nil;
I'm use this, I don't know if is best solution but work.

DatSet.Provider;
DatSet.Close;
DatSet.Open;

Alexis.

Natalie Boodram escribió:

Natalie Boodram

unread,
Apr 7, 1999, 3:00:00 AM4/7/99
to
The query is definitely not active at design time. And I don't touch and of
the Active or Connected properties of the DBDatasets. I thought maybe that
is what I was missing, but I guess not. Basically I ApplyUpdates(-1), close
the client dataset, reopen it and I do not see the changes. (If I don't
close and re-open, the changes are there because they have been made to the
local data.) There are no events for the provider on the server side.

Any help is greatly appreciated.
Thanks,
Natalie

Dan Miser [TeamB] wrote in message ...

Dan Miser [TeamB]

unread,
Apr 7, 1999, 3:00:00 AM4/7/99
to
In article <7efh18$sh...@forums.borland.com>, Natalie Boodram wrote:
> Basically I ApplyUpdates(-1), close
> the client dataset, reopen it and I do not see the changes.
>
Doing just that, I see the changes just fine. Do you have an
CDS.OnReconcileError event assigned? What DBMS are you using? What
version of Delphi? Can you post the steps required to demonstrate this
behavior.

Natalie Boodram

unread,
Apr 7, 1999, 3:00:00 AM4/7/99
to
Dan Miser [TeamB] wrote in message ...
>Doing just that, I see the changes just fine. Do you have an
>CDS.OnReconcileError event assigned? What DBMS are you using? What
>version of Delphi? Can you post the steps required to demonstrate this
>behavior.

I do not have an OnReconcileError event. The changes do get posted to the
database just fine. If I close the application and re-open it, I see the
changes. I am using Oracle 8.0.4, Delphi 4, Update Pack 3.

I created a simple test application to demonstrate this. All there is to it
is a TDatabase, Provider and Query on the server, and a databound grid
connected to the client dataset on the client. When you edit a field in the
grid, I apply updates, close and reopen the cds immediately, but you never
see the modifications. If you close the app and reopen it, the modifications
are there.

Thank you very much for your assistance in this. I really don't have a clue
as to what is wrong.

Here is the server code:
Remote Data Module Unit:
unit RDMTest;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ComServ, ComObj, VCLCom, StdVcl, BdeProv, DataBkr, DBClient,
ServerTest_TLB,
Provider, Db, DBTables;

type
TTest = class(TRemoteDataModule, ITest)
qryTaxes: TQuery;
provTaxes: TDataSetProvider;
Database1: TDatabase;
procedure TestCreate(Sender: TObject);
procedure TestDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
protected
function Get_provTaxes: IProvider; safecall;
end;

var
Test: TTest;

implementation

{$R *.DFM}

function TTest.Get_provTaxes: IProvider;
begin
Result := provTaxes.Provider;
end;

procedure TTest.TestCreate(Sender: TObject);
begin
Database1.Open;
end;

procedure TTest.TestDestroy(Sender: TObject);
begin
Database1.Close
end;

initialization
TComponentFactory.Create(ComServer, TTest,
Class_Test, ciMultiInstance, tmApartment);
end.


Remote Data Module Form:

object Test: TTest
OldCreateOrder = False
OnCreate = TestCreate
OnDestroy = TestDestroy
Left = 532
Top = 262
Height = 150
Width = 215
object qryTaxes: TQuery
DatabaseName = 'TestDB'
SQL.Strings = (
'select * from ATLAS.TAXES')
Left = 84
Top = 44
end
object provTaxes: TDataSetProvider
DataSet = qryTaxes
Left = 152
Top = 44
end
object Database1: TDatabase
AliasName = 'DEV_ORCL'
DatabaseName = 'TestDB'
SessionName = 'Default'
Left = 20
Top = 44
end
end

Client Unit:
unit UpdateTest;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
DBClient, MConnect, SConnect, Grids, DBGrids, Db;

type
TForm1 = class(TForm)
ClientDataSet1: TClientDataSet;
DataSource1: TDataSource;
DBGrid1: TDBGrid;
SocketConnection1: TSocketConnection;
procedure ClientDataSet1AfterPost(DataSet: TDataSet);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}


procedure TForm1.ClientDataSet1AfterPost(DataSet: TDataSet);
begin
ClientDataSet1.ApplyUpdates(-1);
ClientDataSet1.Close;
ClientDataSet1.Open;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
ClientDataSet1.Open;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
ClientDataset1.Close;
end;


end.


Client Form:
object Form1: TForm1
Left = 213
Top = 107
Width = 606
Height = 355
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
OnClose = FormClose
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object DBGrid1: TDBGrid
Left = 8
Top = 12
Width = 581
Height = 253
DataSource = DataSource1
TabOrder = 0
TitleFont.Charset = DEFAULT_CHARSET
TitleFont.Color = clWindowText
TitleFont.Height = -11
TitleFont.Name = 'MS Sans Serif'
TitleFont.Style = []
end
object ClientDataSet1: TClientDataSet
Aggregates = <>
Params = <>
ProviderName = 'provTaxes'
RemoteServer = SocketConnection1
AfterPost = ClientDataSet1AfterPost
Left = 16
Top = 284
end
object DataSource1: TDataSource
DataSet = ClientDataSet1
Left = 48
Top = 284
end
object SocketConnection1: TSocketConnection
ServerGUID = '{06BCBAE3-ECEA-11D2-A461-00104B6B5C29}'
ServerName = 'ServerTest.Test'
Address = '208.130.157.204'
Left = 84
Top = 284
end
end


Dan Miser [TeamB]

unread,
Apr 7, 1999, 3:00:00 AM4/7/99
to
Use a TProvider - not a TDatasetProvider.

Alex Karpenko

unread,
Apr 8, 1999, 3:00:00 AM4/8/99
to borland.public.delphi.database.multi-tier

Dan Miser [TeamB] wrote in message ...
>You don't have to use TDatasetProvider to have control of your updates. You
>can still use TProvider.

Why do I use TDataSetProvider instead of TProvider?
First of all, I need updates to be applied by my own rules. So the
variant when TProvider applies them itself to database works fine, great,
but doesn't suit me. That is ResolveToDataSet = False is not for me.
Then, if I set ResolveToDataSet to True, it doesn't work as I wait for.
I expect that TProvider must update TQuery, istead of applying updates to
database. But no events occur on the TQuery and it stays unupdated at all.
But when I use TDataSetProvider, it applies updates to TQuery according
to the rules I defined in the TUpdateSQL bound to TQuery. Maybe it works a
little slower,
but just as I want. I control the situation totally.


>The ResolveToDataset option means that MIDAS will attempt to resolve the
>changes to the DB using standard Delphi database techniques, i.e. by using
the
>BDE. You do get to use some of the TDBDataset events this way, but it is
much
>slower than the native MIDAS resolving method.

See above. I got no events on TQuery, only on TProvider.

>Maybe... <g> If you're using TUpdateSQL as a place-holder for your queries,
I
>find that to be a very good use of the component in MIDAS. Using it with
>CachedUpdates that you apply yourself to a MIDAS application is redundant.
>Why use CachedUpdates on the server? You don't want updates cached there.

I use CachedUpdates on the server just because if I don't use it, the
Query I get would be read-only, and I wouldn't be in able to update just
TQuery at all. An exception occurs.

0 new messages