Browse Source

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 -
lacak 8 years ago
parent
commit
689fa805eb
1 changed files with 30 additions and 16 deletions
  1. 30 16
      packages/fcl-db/src/sqldb/sqldb.pp

+ 30 - 16
packages/fcl-db/src/sqldb/sqldb.pp

@@ -1964,7 +1964,7 @@ begin
     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
   if UseOldValue then
@@ -1981,36 +1981,36 @@ var
   s   : string;
   x   : integer;
   Fld : TField;
-  P : TParam;
-  B,ReturningClause : Boolean;
+  Par, P : TParam;
+  UseOldValue, HasReturningClause : Boolean;
 
 begin
   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
     ukInsert : begin
                s := Trim(Query.FInsertSQL.Text);
                if s = '' then
-                 s := ConstructInsertSQL(Query, ReturningClause)
+                 s := ConstructInsertSQL(Query, HasReturningClause)
                else
-                 ReturningClause := False;
+                 HasReturningClause := False;
                qry := InitialiseUpdateStatement(Query, Query.FInsertQry);
                end;
     ukModify : begin
                s := Trim(Query.FUpdateSQL.Text);
                if s = '' then begin
                  //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
                else
-                 ReturningClause := False;
+                 HasReturningClause := False;
                qry := InitialiseUpdateStatement(Query, Query.FUpdateQry);
                end;
     ukDelete : begin
                s := Trim(Query.FDeleteSQL.Text);
                if (s='') and (not assigned(Query.FDeleteQry) or (Query.UpdateMode<>upWhereKeyOnly)) then
                  s := ConstructDeleteSQL(Query);
-               ReturningClause := False;
+               HasReturningClause := False;
                qry := InitialiseUpdateStatement(Query, Query.FDeleteQry);
                end;
   end;
@@ -2020,14 +2020,28 @@ begin
   for x:=0 to Qry.Params.Count-1 do
     begin
     P:=Qry.Params[x];
-    S:=p.name;
-    B:=SameText(leftstr(S,4),'OLD_');
-    if B then
+    S:=P.Name;
+    UseOldValue:=SameText(Copy(S,1,4),'OLD_');
+    if UseOldValue then
+      begin
       Delete(S,1,4);
-    Fld:=Query.FieldByName(S);
-    ApplyFieldUpdate(Query.Cursor,P as TSQLDBParam,Fld,B);
+      Fld:=Query.FieldByName(S);
+      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;
-  if ReturningClause then
+  if HasReturningClause then
     begin
     Qry.Close;
     Qry.Open
@@ -2039,7 +2053,7 @@ begin
     Qry.Close;
     DatabaseErrorFmt(SErrFailedToUpdateRecord, [Qry.RowsAffected], Query);
     end;
-  if ReturningClause then
+  if HasReturningClause then
     Query.ApplyReturningResult(Qry,UpdateKind);
 end;