DASchema and businessprocessor that fails to throw an exception

hi,
i had a nasty problem where a DA schema table ‘lost’ the primary key property of a field (i guess as a result of an update to the fields cause i added some fields in the query)
that said, the server side business processor was in a updWhereKeyOnly mode (auto generated update stats)
so since this is a rather difficult situation to auto generate update statements whithout knowing the field of the primary key i would expect the business processor throwing an exception saying just that…
now it falls back to creating a where clause using all fields that are updated so a bit like upWhereAll…
resulting in the most weird and unpredictable update statements…

so i’de really like to see an exception implemented that fires when a businessprocessor is defined as updWhereKeyOnly and the referenced dataset has no primary key defined…

would have saved me a lot of time finding the problem and fixing databases…

Hi,

What version of DAD are you using?
If you are using SQL mode and custom SQL are used, it is as designed.
DAD can’t detect PK from user’s SQL because it can be select from view or some similar case. For SQL mode you should set PK manually.

try to drop query component to form and execute select * from table - PK information will be missed…

SDAC
the problem isn’t that custom sql is used - i get that i need to define the PK myselves…
the problem is that the business process is configured to generate its statements based in updWhereKEYonly…
so imho if there is no field defined as primary key it should throw an exception cause it just can’t generate any statement that is to be trusted to correctly update the desired record…

Hi,

you can change it to any other value:

 TDAUpdateMode = (updWhereKeyOnly, updWhereAll, updWhereKeyAndUserDefined, updWhereUserDefined);

for autogenerated BP you can set it in DataService.OnBusinessProcessorAutoCreated event or just drop TDABusinessProcessor to your DataAbstract service and setup it for your table …

hi Evgeny,

  • i have a businessprocessor on the datamodule for the schema
  • the businessprocessor is set to updWhereKEYonly
  • the businessprocessor referenced datatable is MISSING the primary key field info

since the businessprocessor is setup correctly and since the schema table not since it is missing the primary key field info, it should throw an exception since it can’t proceed updating without knowing the primary key field name…

i don’t see how you last reply is an answer to the problem honestly…
it’s not about changing the update mode, it’s about not honoring the update mode that was set on the business processor
imho this should throw an exception
and frankly i was expection none the less…
it is a safeguard for problems that can and will arise in the schema if one uses custom sql…

so the real question is why it does not throw an exception and if so, can this behaviour can be changed in a future release (or be configured to throw an exception)
it’s the only way of having some kind of runtime check to see if the primkey field is defined…

Hi,

we use this logic:

if (aDelta.KeyFieldCount = 0) and (lUpdateMode = updWhereKeyOnly) then lUpdateMode := updWhereAll;

You can check for PK and set own value …

i don’t want to check for PK…
what is the point of auto generate statements in a business processor when you define updWhereKEYonly when there is no PK field present in the schema table?
i should be a safeguard…
hence the logic :
if (aDelta.KeyFieldCount = 0) and (lUpdateMode = updWhereKeyOnly) then lUpdateMode := updWhereAll;
should not exists imho and instead throw an exception
cause this alters the way the auto generated statements are intended to be generated

i don’t like that behaviour defined in a component using a property of that component changes like the intended behaviour…

Hi,

this logic is present since beginning for 20+ years.

if you dislike this behavior, you can check for aDelta.KeyFieldCount = 0 and raise exception in events like TDataAbstractService.OnBeforeProcessDeltas or TDABusinessProcessor.OnBeforeProcessDelta

I agree with Marc here. updWhereKeyOnly should fail, if there IS no primary key set, because thats clearly an unexpected error condition, and cannot work.

—marc

Logged as bugs://D19481.

bugs://D19481 was closed as fixed.

Hi,

  • update uDABusinessProcessor.pas as

old line:

if (aDelta.KeyFieldCount = 0) and (lUpdateMode = updWhereKeyOnly) then lUpdateMode := updWhereAll;

new line:

DAError((aDelta.KeyFieldCount = 0) and (lUpdateMode = updWhereKeyOnly), 'updWhereKeyOnly mode is incompatible with delta that has no primary keys');
  • close Delphi IDE
  • launch C:\Program Files (x86)\RemObjects Software\Build\install_DA.cmd with admin rights