Bypass reduceddelta

hi,
is there a way to always have a field updated even when using reduceddelta?

hi,

in reduced delta mode, only changed fields are included into delta change.
by other words, if you have table with 100 fields, only PK and changed fields will be put to delta.

as a workaround, you can specify some fields as a PK and they will be included always even if reduced delta mode is set

i’ll try setting that property on the fly at client side
but will that result in side effects for updating?
since serverside i will be updating upwherekeyonly so i guess it will take that other field into account also?

setting .inprimarykey at clientside does not seem to work…

hmm, we have this code in TDABusinessProcessor.GenerateSQL2 that disallows to update non-changed fields in ReducesDelta mode:

// skip generating field in case it wasn't changed
if lReducesDeltaMode and ROVariantsEqual(aChange.OldValues[i],aChange.NewValues[i]) then Continue;

so one solution - don’t use ReducesDelta mode

yep saw that code also…
but not using reduceddelta isn’t an option either…

i could misuse the required property but then i need to alter DA code also which i want to stay away from…
the problem is that i need to update a field which isn’t changed in context A but may have been changed in context B while A isn’t applied yet, BUT the non changed value of context A has precedence over B which has changed that value…

any chance on getting a client side ‘always save’ property on the field?

is there a way to solve this using serverside businessrules ?
manipulating the old value in one way or another?

i don’t see a way to manipulating the old value of the field which would solve my problem
is there a way to alter the oldvalue serverside in businessrule?

in general, adding this field into BP.UserUpdateFields with BP.UpdateMode = updWhereKeyAndUserDefined or adding this field into PK will solve this issue because update command will be generated with where myfield = :myfield and ... so this update will be applied only if myfield has unchanged value and failed if this value was changed

that is not what i want
i know that the value will be different from the value i’m applying… but for the dataset it is still the same so old and new values are the same
it’s basically resetting a kind of flag
so i want this to happen regardless if it is changed or not
adding it to the pk does not solve cause nothing gets persisted like you said…

is it matter for you, how update will be performed - in single update or in two ones?
you can manually perform update like

update mytable set myfield = :myfield where ...

after specific update change was applied

it can be done in BP.OnBeforeProcessChange if change was successful

trying something like this but does not seem to work:

if aChangeType = ctUpdate then
begin
if VarIsNull(aChange.NewValueByName[fieldname]) then
begin
aChange.OldValueByName[fieldname] := Null;
aChange.NewValueByName[fieldname] := 0;
end;

clientside i’m setting fieldnameIsNull := True;
but the aChange.NewValueByName[fieldname] value is not null in this event, in debug it says it is not assigned…?
or is this behaviour by design? setting fieldnameIsNull := true sets newvalue to nil?

where do you set this? client or server-side? what event?

Do you use table rules, if yes, it just set value to Null:

        Write(Format('procedure T%sDataTableRules.Set%sIsNull(const aValue: Boolean);', [lDataset_ValidID, lField_ValidID]));
        Write('begin');
        Write('  if aValue then');
        Write(Format('    DataTable.Fields[idx_%s%s].AsVariant := Null;', [lDataset_ValidID, lField_ValidID]));
        Write('end;');

setting the fieldvalue to null does not work cause at serverside the oldvalue is not assigned rather than varisnull(oldvalue)

setting the fieldvalue to an arbitrary value does seem to work, i can test for that value serverside and switch them so the field does get updated…
this obviously only works cause the value that need to be written is known at serverside (fixed value)…

try to set oldvalue to null before sending update to server?
it can be done via table.Delta.change[x].OldValueByName('name') := Null; before calling table.ApplyUpdate;

ah so i can do it at client side also?

how do i determine change[x] ?

you can detect it in loop via comparing PK values, but as I understand your case it also can be done like

for i := 0 to table.Delta.Count-1 do 
  if table.Delta.change[i].OldValueByName('myfield') = table.Delta.change[i].NewValueByName('myfield') then
    table.Delta.change[i].OldValueByName('myfield') := Null;

ok but isn’t there a way to immediatly get the X based on the current row or is the changes collections not in relation to the record pointer?