Watch, Follow, &
Connect with Us
Public Report
Report From: Delphi-BCB/Midas/TDataSetProvider    [ Add a report in this area ]  
Report #:  4006   Status: Closed
DB 'current' values after an update conflict (Record not found or changed by another user) is against the wrong fields
Project:  Delphi Build #:  6.240
Version:    7.0 Submitted By:   Dave Rowntree
Report Type:  Basic functionality failure Date Reported:  4/4/2003 9:02:00 AM
Severity:    Commonly encountered problem Last Updated: 10/6/2006 6:50:56 AM
Platform:    95, 98, 2000, NT, XP Internal Tracking #:   159437
Resolution: Fixed (Resolution Comments) Resolved in Build: : 7.0.8.1
Duplicate of:  None
Voting and Rating
Overall Rating: No Ratings Yet
0.00 out of 5
Total Votes: None
Description
When the DSP obtains the DB 'current' values after an update conflict (Record not found or changed by another user), it does so against the wrong fields. The fields it requests current values for should be the same as the fields in the update where clause, but they are not.

DSP.GenSelectSQL generates the select statement (for TSQLResolver.InitializeConflictBuffer) and it's field selection criteria is incorrect.

DSP.GenSelectSQL is also called by TDataSetProvider.GetDataSetFromDelta, which is used by CDS.RefreshRecord. The field selection criteria is incorrect for that requirement as well (see QC????). Since the field selection criteria is different for these two requirements, two seperate functions would seem to be the way to go.
Steps to Reproduce:
1. download the test case app from Attachments.
2. Open the test case app in Delphi.
3. Follow the on screen steps.
Workarounds
PROVIDER.PAS
(**) (* Delphi 6.0 - 7.01 *)
(* Fix to correct the obtaining of current db values after an update
   conflict. This fix returns current values for fields that would
   have been in the update 'where' clause. Without this fix, just
   fields containing a pfInWhere flag have current values returned *)
(* Dave Rowntree 04/01/03 *)
procedure TSQLResolver.InitializeConflictBuffer(Tree: TUpdateTree);
var
  Alias: string;

(**) (* add this function *)
  function GenConflictSelectSQL(Tree: TUpdateTree; SQL: TStrings):Boolean;
  var
    i: Integer;
    Temp: string;
  begin
    Result := False;
    with PSQLInfo(Tree.Data)^ do
    begin
      SQL.Add('select');
      for i := 0 to Tree.Delta.FieldCount - 1 do
        if UseFieldInWhere(Tree.Delta.Fields[i], Provider.UpdateMode) then
        begin
          SQL.Add(Format(' %s%s%s%1:s,',
            [QuotedTableDot, QuoteChar, Tree.Delta.Fields[i].Origin]));
          Result := True;
        end;
      if Result then
      begin
        { Remove last ',' }
        Temp := SQL[SQL.Count-1];
        SQL[SQL.Count-1] := Copy(Temp, 1, Length(Temp) - 1);
        SQL.Add(Format(' from %s %s',[QuotedTable, Alias]));     { Do not localize }
      end;
    end;
  end;

begin
  if PSQLInfo(Tree.Data)^.HasObjects then Alias := DefAlias else Alias := '';
  FSQL.Clear;
  FParams.Clear;
  //GenSelectSQL(Tree, FSQL, FParams, Alias);               (**) (* rem out this line *)
  if GenConflictSelectSQL(Tree, FSQL) then                  (**) (* add this line *)
  begin                                                     (**) (* add this line *)
    GenWhereSQL(Tree, FSQL, FParams, upWhereKeyOnly, Alias);(**) (* add this line *)
    DoGetValues(FSQL, FParams, Tree.Delta);                 (**) (* add this line *)
  end;                                                      (**) (* add this line *)
end;

---------

PROVIDER.PAS
(**) (* Delphi 6.0 - 7.01 *)
(* Fix to correct the obtaining of current db values after an update
   conflict. This fix returns current values for fields that would
   have been in the update 'where' clause. Without this fix, just
   fields containing a pfInWhere flag have current values returned *)
(* Dave Rowntree 04/01/03 *)
procedure TSQLResolver.InitializeConflictBuffer(Tree: TUpdateTree);
var
  Alias: string;

(**) (* add this function *)
  function GenConflictSelectSQL(Tree: TUpdateTree; SQL: TStrings):Boolean;
  var
    i: Integer;
    Temp: string;
  begin
    Result := False;
    with PSQLInfo(Tree.Data)^ do
    begin
      SQL.Add('select');
      for i := 0 to Tree.Delta.FieldCount - 1 do
        if UseFieldInWhere(Tree.Delta.Fields[i], Provider.UpdateMode) then
        begin
          SQL.Add(Format(' %s%s%s%1:s,',
            [QuotedTableDot, QuoteChar, Tree.Delta.Fields[i].Origin]));
          Result := True;
        end;
      if Result then
      begin
        { Remove last ',' }
        Temp := SQL[SQL.Count-1];
        SQL[SQL.Count-1] := Copy(Temp, 1, Length(Temp) - 1);
        SQL.Add(Format(' from %s %s',[QuotedTable, Alias]));     { Do not localize }
      end;
    end;
  end;

begin
  if PSQLInfo(Tree.Data)^.HasObjects then Alias := DefAlias else Alias := '';
  FSQL.Clear;
  FParams.Clear;
  //GenSelectSQL(Tree, FSQL, FParams, Alias);               (**) (* rem out this line *)
  if GenConflictSelectSQL(Tree, FSQL) then                  (**) (* add this line *)
  begin                                                     (**) (* add this line *)
    GenWhereSQL(Tree, FSQL, FParams, upWhereKeyOnly, Alias);(**) (* add this line *)
    DoGetValues(FSQL, FParams, Tree.Delta);                 (**) (* add this line *)
  end;                                                      (**) (* add this line *)
end;
Attachment
4006.zip
Comments

Daniel Serrano at 1/26/2007 8:00:07 PM -
HI:

I have the same error, please send me the fix. is very important.

Greetings from Per

Daniel Serrano

Server Response from: CODE1