Watch, Follow, &
Connect with Us
Public Report
Report From: Delphi-BCB/Midas/TClientDataSet    [ Add a report in this area ]  
Report #:  2717   Status: Closed
Incorrect ChangeCount with TWideStringField
Project:  Delphi Build #:  4.453
Version:    7.0 Submitted By:   Dave Rowntree
Report Type:  Basic functionality failure Date Reported:  10/23/2002 3:55:47 AM
Severity:    Commonly encountered problem Last Updated: 12/15/2006 4:02:58 AM
Platform:    95, 98, 2000, NT, XP Internal Tracking #:   149808
Resolution: Fixed (Resolution Comments) Resolved in Build: : 7.0.8.1
Duplicate of:  None
Voting and Rating
Overall Rating: (5 Total Ratings)
4.60 out of 5
Total Votes: 3
Description
If the value of a TWideStringField is changed and posted, then changed back to it's original value and posted, the resulting CDS.ChangeCount is incorrect. It should be zero, but it is one.

This problem does not occur with a TStringField.
Steps to Reproduce:
1. Download, unzip, compile and run the application provided in Attachments.
2. Follow the on-screen steps.

See also 167223
Workarounds
(3/12/2003 - updated workaround per discussions with dave rowntree in NG)

well it's not pretty, but it seems to work for me.  Create a BeforeUpdateRecord event handler for the CDS.  Call bugdodger from inside, passing all parameters (as shown)
BugDodger will analyze old and new values (if the field has pfInUpdate); and not allow the change to be applied if ALL fields have no differences between old and new values.
WARNING - SQLDataSet and ClientDataSet MUST have fields in the same order, since bugdodger uses positional parameters only...
hope this helps!



procedure TSomeForm.SomeDSPBeforeUpdateRecord(Sender: TObject; SourceDS: TDataSet; DeltaDS: TCustomClientDataSet; UpdateKind: TUpdateKind; var Applied: Boolean);
begin    
    BugDodgerQC2717(Sender, SourceDS, DeltaDS, UpdateKind, Applied);
end;

procedure TSomeForm.BugDodgerQC2717(Sender: TObject; SourceDS: TDataSet; DeltaDS: TCustomClientDataSet; UpdateKind: TUpdateKind; var Applied: Boolean);
var i: cardinal;
begin
    if UpdateKind = ukModify then begin
        Applied := TRUE;
        for i := 0 to pred(DeltaDS.FieldCount) do begin
            If (not VarIsEmpty(DeltaDS.Fields[i].NewValue))
               and (DeltaDS.Fields[i].NewValue <> DeltaDS.Fields[i].OldValue)
               and (pfInUpdate in DeltaDS.Fields[i].ProviderFlags) then begin      
                     Applied := FALSE;
                     break;   // no sense checking the rest...
            end;
        end;
    end;
end;
Attachment
2717.zip
Comments

wayne hubbard at 10/23/2002 3:07:49 PM -
I disagree with your rating of "infrequently encountered", since,
for example, the simple act of opening a TDBLookupComboBox
to see what your choices are, and closing it with the same choice,
is enough to shift the CDS into edit mode, which will later (using
text-book code) cause a post, requiring an applyupdates, and
viola'!   Exception.  This is exactly how I discovered it and given
the nature of things, it seems to me that this failure would most likely
show up during a demo or training session on your new app, the
exact places you'd want to see it the least.

Nevertheless, I thank you for your time and energy, and especially
for posting it on QC - which I was intending to ask you to do
anyway, since despite ratings and votes, et.al., it seems clear to me
that name recognition helps toward getting things considered sooner,
if at all....

Dave Rowntree at 10/24/2002 8:35:12 AM -
I'd be interested to know why you have taken two paragraphs from a dbexpress newsgroup posting from Paladin to myself, and posted it here as if it is from you?

wayne hubbard at 10/24/2002 11:45:27 PM -
sorry to confuse.
I was advised not to publish my real
name, company, email, etc. in the NG's
I think its good advice.

paladin is my  nom de plume

Dave Rowntree at 10/28/2002 5:27:09 AM -
I see.

Dave Rowntree at 10/24/2002 8:58:22 AM -
I have changed the Severity to 2.

wayne hubbard at 3/22/2003 12:58:51 PM -
3/22/2003

I don't know why on earth QC doesn't make unprocessed workarounds visible as soon as they are posted.  Some poor soul searching for help finds the exact description of his problem and ~still~ can't get help fixing it until what???  Some one has to *approve* unprocessed workarounds?  sheesh.
Anyway, here it is in comments.  I hope it helps someone.

// ---------------------------------------------------------------------------------------------------------- //

(3/12/2003 - updated workaround per discussions with dave rowntree in NG)

well it's not pretty, but it seems to work for me.  Create a BeforeUpdateRecord event handler for the CDS.  Call bugdodger from inside, passing all parameters (as shown)
BugDodger will analyze old and new values (if the field has pfInUpdate); and not allow the change to be applied if ALL fields have no differences between old and new values.
WARNING - SQLDataSet and ClientDataSet MUST have fields in the same order, since bugdodger uses positional parameters only...
hope this helps!

procedure TSomeForm.SomeDSPBeforeUpdateRecord(Sender: TObject; SourceDS: TDataSet; DeltaDS: TCustomClientDataSet; UpdateKind: TUpdateKind; var Applied: Boolean);
begin    
    BugDodgerQC2717(Sender, SourceDS, DeltaDS, UpdateKind, Applied);
end;

procedure TSomeForm.BugDodgerQC2717(Sender: TObject; SourceDS: TDataSet; DeltaDS: TCustomClientDataSet; UpdateKind: TUpdateKind; var Applied: Boolean);
var i: cardinal;
begin
    if UpdateKind = ukModify then begin
        Applied := TRUE;
        for i := 0 to pred(DeltaDS.FieldCount) do begin
            If (not VarIsEmpty(DeltaDS.Fields[i].NewValue))
               and (DeltaDS.Fields[i].NewValue <> DeltaDS.Fields[i].OldValue)
               and (pfInUpdate in DeltaDS.Fields[i].ProviderFlags) then begin      
                     Applied := FALSE;
                     break;   // no sense checking the rest...
            end;
        end;
    end;
end;

Dave Rowntree at 5/11/2004 3:26:42 AM -
Fixed in Midas.dll

Server Response from: CODE1