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/TClientDataSet
[ Add a report in this area ]
Report #:
4508
Status:
Closed
ChangeCount being incremented when data has not changed.
Project:
Delphi
Build #:
7.0.4.453
Version:
7.0
Submitted By:
Dave Rowntree
Report Type:
Basic functionality failure
Date Reported:
5/20/2003 11:39:23 AM
Severity:
Serious / Highly visible problem
Last Updated:
10/6/2006 6:51:00 AM
Platform:
95, 98, 2000, NT, XP
Internal Tracking #:
167223
Resolution:
Fixed
(Resolution Comments)
Resolved in Build:
:
7.0.8.1
Duplicate of:
None
Voting and Rating
Overall Rating:
(1 Total Rating)
5.00 out of 5
Total Votes:
1
Description
ChangeCount being incremented when data has not changed.
If a CDS TStringField or a TWideStringField containing only a few characters, has it's current data value re-entered, then posted, the CDS conciders a data change has occured and increments the ChangeCount. This is incorrect. A Delta is created where the changes indicated in the ukModified Delta record are identical to the original values.
If the CDS is being provided from a dbExpress data access layer against a MySQL database, the dbexpress problem described in QC#4504 will cause a 'Record not found or changed by another user' error when CDS.ApplyUpdates(0) is called.
Steps to Reproduce:
1. Download the test case app from Attachments.
2. The Tables.zip file contains the three files for the MySQL table which should be copied into your MySQL\Data\test directory.
3. The Tables.zip also contains an SQL script file for creating the required table in MSSQL.
4. Open the test case app in Delphi.
5. Alter the MSSQL connection component to point to the appropriate database.
6. Run the app in Delphi.
7. Follow the on screen instructions.
Workarounds
PROVIDER.PAS
(**) (* Delphi 6.0 - 7.0 *)
(* QC#4508 workaround. Prevents attempted DB updates where the field
values have not changed in TStringField and/or TWideStringField.
NOTE: IF YOU USE THIS FIX YOU *MUST* ALSO USE MY FIX AGAINST QC#2338 (in Provider.pas) *)
(* Dave Rowntree 05/29/03 *)
function TCustomResolver.InternalUpdateRecord(Tree: TUpdateTree): Boolean;
var
RecNoSave: Integer;
Applied: Boolean;
UpdateKind: TUpdateKind;
E: Exception;
PrevErr, Err: EUpdateError;
i: integer; (* add this line *)
v: variant; (* add this line *)
begin
PrevErr := nil;
Err := nil;
Tree.Delta.UseCurValues := False;
while True do
try
UpdateKind := Tree.Delta.UpdateKind;
if ((UpdateKind = ukInsert) and (FPrevResponse in [rrMerge, rrApply])) or
((FPrevResponse = rrMerge) and Tree.Delta.HasMergeConflicts) then
DatabaseError(SInvalidResponse);
Applied := False;
// check that no update TStringFields/TWideStringFields with unchanged values
// check that no update TStringFields/TWideStringFields with unchanged values
// exist in the Delta for ukModify ...
if UpdateKind = ukModify then (* add this line *)
with Tree.Delta do (* add this line *)
for i := 0 to Fieldcount -1 do (* add this line *)
if Fields[i].DataType in [ftString, ftWideString] then (* add this line *)
begin (* add this line *)
v := Fields[i].NewValue; (* add this line *)
if not VarIsEmpty(v) and (v = Fields[i].OldValue) then (* add this line *)
DSBase.PutBlank(ActiveBuffer,0,Fields[i].Index+1,BLANK_NOTCHANGED); (* add this line *)
end; (* add this line *)
RecNoSave := Tree.Delta.RecNo;
try
if Assigned(Provider.BeforeUpdateRecord) then
Provider.BeforeUpdateRecord(Provider, Tree.Source, Tree.Delta, UpdateKind, Applied);
finally
---------
PROVIDER.PAS
(**) (* Delphi 6.0 - 7.0 *)
(* QC#4508 workaround. Prevents attempted DB updates where the field
values have not changed in TStringField and/or TWideStringField.
NOTE: IF YOU USE THIS FIX YOU *MUST* ALSO USE MY FIX AGAINST QC#2338 (in Provider.pas) *)
(* Dave Rowntree 05/29/03 *)
function TCustomResolver.InternalUpdateRecord(Tree: TUpdateTree): Boolean;
var
RecNoSave: Integer;
Applied: Boolean;
UpdateKind: TUpdateKind;
E: Exception;
PrevErr, Err: EUpdateError;
i: integer; (* add this line *)
v: variant; (* add this line *)
begin
PrevErr := nil;
Err := nil;
Tree.Delta.UseCurValues := False;
while True do
try
UpdateKind := Tree.Delta.UpdateKind;
if ((UpdateKind = ukInsert) and (FPrevResponse in [rrMerge, rrApply])) or
((FPrevResponse = rrMerge) and Tree.Delta.HasMergeConflicts) then
DatabaseError(SInvalidResponse);
Applied := False;
// check that no update TStringFields/TWideStringFields with unchanged values
// exist in the Delta ...
with Tree.Delta do (* add this line *)
for i := 0 to Fieldcount -1 do (* add this line *)
if Fields[i].DataType in [ftString, ftWideString] then (* add this line *)
begin (* add this line *)
v := Fields[i].NewValue; (* add this line *)
if not VarIsEmpty(v) and (v = Fields[i].OldValue) then (* add this line *)
DSBase.PutBlank(ActiveBuffer,0,Fields[i].Index+1,BLANK_NOTCHANGED); (* add this line *)
end; (* add this line *)
RecNoSave := Tree.Delta.RecNo;
try
if Assigned(Provider.BeforeUpdateRecord) then
Provider.BeforeUpdateRecord(Provider, Tree.Source, Tree.Delta, UpdateKind, Applied);
finally
Attachment
4508.zip
Comments
Tarvo Hirs at 5/21/2003 3:32:13 AM
-
Seems like a classic case to me, not only a CDS specific feature.
How about this workaround:
if cdsStringField1.AsString <> newValue then
begin
cds.Edit;
cdsStringField1.AsString:= newValue;
cds.Post;
end;
Dave Rowntree at 5/22/2003 3:24:47 AM
-
Tarvo Hirs said - "Seems like a classic case to me"
Not really, no.
" not only a CDS specific feature.
"
This is a very CDS specific problem. The Midas.dll is incorrectly determining whether a change has occured to a field value.
Dave Rowntree at 5/11/2004 3:29:59 AM
-
Fixed in Midas.dll
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