Log On
Embarcadero Home
Watch, Follow, &
Connect with Us
QualityCentral
Communities
Articles
Blogs
Resources
Downloads
Help
Quality Central
Delphi-BCB
Midas
Install
Java Midas
Socket Server
TClientDataSet
TDataSetProvider
TDCOMConnection
TMidasConnection
TOLEEnterpriseConnection
TProvider
TRemoteServer
TSimpleObjectBroker
TSocketConnection
TWebConnection
WebMidas
XML Midas
You are not logged in.
Help
Print
Public Report
Report From:
Delphi-BCB/Midas/TProvider
[ Add a report in this area ]
Report #:
3515
Status:
Closed
PacketRecords with params will fail if recordcount > packetrecords number.
Project:
Delphi
Build #:
4.453
Version:
7.0
Submitted By:
Michael JEWEL
Report Type:
Basic functionality failure
Date Reported:
2/11/2003 5:37:05 AM
Severity:
Commonly encountered problem
Last Updated:
10/6/2006 6:50:54 AM
Platform:
All platforms
Internal Tracking #:
157503
Resolution:
Fixed
(Resolution Comments)
Resolved in Build:
:
7.0.8.1
Duplicate of:
None
Voting and Rating
Overall Rating:
(7 Total Ratings)
4.57 out of 5
Total Votes:
5
Description
If there is a parameter and the recordcount is greater than the packetrecords, the clientdataset never reaches the EOF and receices always and always the same packet that make all the application looping!
The problem was not present with Delphi 6, only appears in Delphi 7.
Dave Rowntree's coment:
"This is a D7 MIDAS bug. It only affects Delphi's default
incremental fetching where the CDS (and DSP.DataSet) have Params.
The code
> if VarIsEmpty(Params) and (Self.Params.Count > 0) then
> Params := PackageParams(Self.Params);
was added to D7 DoGetRecords to force CDS.Refresh to honour the CDS params
(which D<7 does not do).
The trouble is, it also affects CDS.FetchMoreData and CDS.GetNextPacket, which are used for automatic and manual control of incremental fetching.
This code causes the DSP.DataSet to be closed when the DSP.DataSet Params are set, thereby loosing the incremental fetching position, so the *first* CDS.PacketRecords number of records are returned every time by CDS.FetchMoreData and CDS.GetNextPacket."
Steps to Reproduce:
You can do a very simple test to reproduce the situation: (Delphi 7)
Projet, new app:
- Drop a Database connection and a query returing many rows (ex: 50) with a dummy parameter (BDE, ADO or DBX change nothing, as you prefer)
- drop a DataSetprovider and a ClientDataSet
- Link these components between them.
- Set Packetrecords to the clientdataset to a value smaller than the total recordcount of the rows (ex: 10)
- Drop a button, and on the OnClik event just make a simple loop:
ClientDataSet1.close;
ClientDataSet1.FetchParams;
ClientDataSet1.Params.ParamByName('paramdummy').AsString := '...';
ClientDataSet1.open;
ClientDataSet1.first;
while not ClientDataSet1.eof do
begin
ClientDataSet1.next;
end;
showmessage('done');
- you can add a DataSource and a dBgrid to see exactly what append...
- Then run and click: The Showmessage(done') never appears because the clientdataset never reachs the eof value.
Workarounds
PROVIDER.PAS
(**)(* Delphi 7.0 - 7.1 *)
(* fix for QC3515. Allows incremental fetching to be used with CDS Params *)
(* Dave Rowntree 03/12/2003 *)
function TDataSetProvider.InternalGetRecords(Count: Integer; out RecsOut: Integer;
Options: TGetRecordOptions; const CommandText: WideString;
var Params: OleVariant): OleVariant;
begin
try
if grReset in Options then
begin
Reset;
{ When doing only a reset and not getting more data then exit }
if Count = 0 then Exit;
end;
if not DataSet.Active then
begin
DataSet.Open;
FDataSetOpened := True;
if FRecordsSent > 0 then DataSet.MoveBy(FRecordsSent);(**)(* add this line *)
end;
if (Count = 0) or (grMetaData in Options) then
---------
(**)(* QC#8128 fix - Loss of DSP.DataSet.Param value causing zero records to be returned *)
(* D7.1 *)
(* Mark Eddington 18 May 2004 *)
procedure TDataSetProvider.SetParams(Values: OleVariant);
var
DataSetParams: TParams;
begin
if VarIsClear(Values) then Exit;
CheckDataSet;
DataSetParams := IProviderSupport(DataSet).PSGetParams;
if not Assigned(FParams) then
FParams := TParams.Create;
FParams.Clear;
UnpackParams(Values, FParams);
if not (Assigned(DataSetParams) and DataSetParams.IsEqual(FParams)) then
IProviderSupport(DataSet).PSSetParams(FParams);
end;
Attachment
3515.zip
Comments
Jan Bia at 11/18/2003 1:24:03 AM
-
after fix
cds.Close;
cds.Params[0].Value := NewValue;
cds.Open;
returns wrong records
- cds.Open probably fetchs records with old fetching position
Dave Rowntree at 2/3/2004 1:50:13 AM
-
No, it doesn't return the wrong records, it works ok.
The only way what you describe is likely to happen is if you have set the TDataSetProvider.Option poNoReset to True. This you should never do if you are using MIDAS default incremental fetching (CDS.PacketRecords > 0).
Petr Bejlek at 3/10/2004 2:15:31 AM
-
It seems to be the same problem as reported in reports # 5664, 4498
Dave Rowntree at 5/26/2004 1:44:37 AM
-
Workaround fix ...
There are two VCL fixes in the Workaround tab.
Please remove the fix provided in the TDataSetProvider.InternalGetRecords procedure from your provider.pas.
Please use the replacement TDataSetProvider.SetParams procedure as a fix for this problem.
Thank you.
Exonet New Zealand Limited Developer at 8/23/2004 5:39:28 PM
-
HI
My problem is very similar... its on MSSQL database.
I think the problem lies in the providers.pas DataSetProvider.SetParams routine and the line where DatasetParams.Isequal (FParams) is tested.
On the client side when the CLientDataset SQL is parsed and a parameter is found it creates a parameter of Paramtype of ptUnknown.
On the Server side when ADO Parameter is set to the TParam properties it
does a paramtype check which is in the routine
AODB.TParameter.Assign(Source: TPersistent);
procedure AssignParam(Param: TParam);
begin
if Param.ParamType = ptUnknown then
Direction := pdInput else
Direction := TParameterDirection(Param.ParamType);
/// IT CHANGES THE PARAMTYPE TO INPUT
end;
So the paramtype is NOT exactly mirrored which means that the result of type TParams of the line DataSetParams := IProviderSupport(DataSet).PSGetParams in the provider.pas TDataSetProvider.SetParams routine will pass back parameters of paramtype ptInput whereas the client has the paramtype of ptunkown and therefore the DB.IsEqual routine will return false and PSSetParams gets called and the dataset is closed..
so the workaround for my problem i see as commenting the lines ( as suggested before) in the DBClient.pas unit or doctoring the DB.Isequal routine or change the DB.ParseSQL routine and default the paramtype to ptinput..
Maybe somebody with a better understand of the MIDAS architecture can recommned what solution is more correct / recommended.
Thanks
Edwin Das
View Your Reports
Search
Server Response from: CODE1
Developer Tools
Blackfish SQL
C++Builder
Delphi
Delphi for PHP
Delphi Prism
InterBase
JBuilder
J Optimizer
3rdRail & TurboRuby
Database Tools
Change Manager
DBArtisan
DB Optimizer
ER/Studio
Performance Center
Rapid SQL
Technical Articles
Tutorials
White Papers
Press Releases
Newsletters
Add Content (GetPublished)
Audio
Audio & Video
Video
Bugs & Suggestions (QualityCentral)
Discussion Forums
Examples (CodeCentral)
Tags
Technology Partners
Downloads
Free Trials
Registered User Downloads
Beta Programs
Add Content (GetPublished)
Articles
Blogs
Bugs & Suggestions (QualityCentral)
Chats
Discussion Forums
Examples (CodeCentral)
Member Services
About
Connect with Us