fcl-db: sqldb: when applying updates to modified record, look for parameter ":field_name" in InsertSQL,UpdateSQL,DeleteSQL first in TFields and if not found then in TParams. Bug #31411

git-svn-id: trunk@35486 -
This commit is contained in:
lacak 2017-02-28 12:03:24 +00:00
parent ffd6465563
commit 689fa805eb

View File

@ -1964,7 +1964,7 @@ begin
end; end;
end; end;
procedure TSQLConnection.ApplyFieldUpdate(C : TSQLCursor; P : TSQLDBParam;F : TField; UseOldValue : Boolean); procedure TSQLConnection.ApplyFieldUpdate(C : TSQLCursor; P : TSQLDBParam; F : TField; UseOldValue : Boolean);
begin begin
if UseOldValue then if UseOldValue then
@ -1981,36 +1981,36 @@ var
s : string; s : string;
x : integer; x : integer;
Fld : TField; Fld : TField;
P : TParam; Par, P : TParam;
B,ReturningClause : Boolean; UseOldValue, HasReturningClause : Boolean;
begin begin
qry:=Nil; qry:=Nil;
ReturningClause:=(sqSupportReturning in ConnOptions) and not (sqoRefreshUsingSelect in Query.Options) and (Trim(Query.RefreshSQL.Text)=''); HasReturningClause:=(sqSupportReturning in ConnOptions) and not (sqoRefreshUsingSelect in Query.Options) and (Trim(Query.RefreshSQL.Text)='');
case UpdateKind of case UpdateKind of
ukInsert : begin ukInsert : begin
s := Trim(Query.FInsertSQL.Text); s := Trim(Query.FInsertSQL.Text);
if s = '' then if s = '' then
s := ConstructInsertSQL(Query, ReturningClause) s := ConstructInsertSQL(Query, HasReturningClause)
else else
ReturningClause := False; HasReturningClause := False;
qry := InitialiseUpdateStatement(Query, Query.FInsertQry); qry := InitialiseUpdateStatement(Query, Query.FInsertQry);
end; end;
ukModify : begin ukModify : begin
s := Trim(Query.FUpdateSQL.Text); s := Trim(Query.FUpdateSQL.Text);
if s = '' then begin if s = '' then begin
//if not assigned(Query.FUpdateQry) or (Query.UpdateMode<>upWhereKeyOnly) then // first time or dynamic where part //if not assigned(Query.FUpdateQry) or (Query.UpdateMode<>upWhereKeyOnly) then // first time or dynamic where part
s := ConstructUpdateSQL(Query, ReturningClause); s := ConstructUpdateSQL(Query, HasReturningClause);
end end
else else
ReturningClause := False; HasReturningClause := False;
qry := InitialiseUpdateStatement(Query, Query.FUpdateQry); qry := InitialiseUpdateStatement(Query, Query.FUpdateQry);
end; end;
ukDelete : begin ukDelete : begin
s := Trim(Query.FDeleteSQL.Text); s := Trim(Query.FDeleteSQL.Text);
if (s='') and (not assigned(Query.FDeleteQry) or (Query.UpdateMode<>upWhereKeyOnly)) then if (s='') and (not assigned(Query.FDeleteQry) or (Query.UpdateMode<>upWhereKeyOnly)) then
s := ConstructDeleteSQL(Query); s := ConstructDeleteSQL(Query);
ReturningClause := False; HasReturningClause := False;
qry := InitialiseUpdateStatement(Query, Query.FDeleteQry); qry := InitialiseUpdateStatement(Query, Query.FDeleteQry);
end; end;
end; end;
@ -2020,14 +2020,28 @@ begin
for x:=0 to Qry.Params.Count-1 do for x:=0 to Qry.Params.Count-1 do
begin begin
P:=Qry.Params[x]; P:=Qry.Params[x];
S:=p.name; S:=P.Name;
B:=SameText(leftstr(S,4),'OLD_'); UseOldValue:=SameText(Copy(S,1,4),'OLD_');
if B then if UseOldValue then
begin
Delete(S,1,4); Delete(S,1,4);
Fld:=Query.FieldByName(S); Fld:=Query.FieldByName(S);
ApplyFieldUpdate(Query.Cursor,P as TSQLDBParam,Fld,B); end
else
Fld:=Query.FindField(S);
if Assigned(Fld) then
ApplyFieldUpdate(Query.Cursor, P as TSQLDBParam, Fld, UseOldValue)
else
begin
// if does not exists field with given name, try look for param
Par:=Query.Params.FindParam(S);
if Assigned(Par) then
P.Assign(Par)
else
DatabaseErrorFmt(SFieldNotFound,[S],Query); // same error as raised by FieldByName()
end;
end; end;
if ReturningClause then if HasReturningClause then
begin begin
Qry.Close; Qry.Close;
Qry.Open Qry.Open
@ -2039,7 +2053,7 @@ begin
Qry.Close; Qry.Close;
DatabaseErrorFmt(SErrFailedToUpdateRecord, [Qry.RowsAffected], Query); DatabaseErrorFmt(SErrFailedToUpdateRecord, [Qry.RowsAffected], Query);
end; end;
if ReturningClause then if HasReturningClause then
Query.ApplyReturningResult(Qry,UpdateKind); Query.ApplyReturningResult(Qry,UpdateKind);
end; end;