Quote
Kjell Rilbe <kjell.ri...@upec.se> wrote:
>Philip Cain wrote:
>> You are right to set the Dataset property of each UpdateSQL. After
>> that, you must consider two things.
>> 1. Set the value back to nil when you close the form or destroy the
>> data module that the UpdateSQL components are on. If you do not, then
>> Delphi can run into access violations.
>OK, can't see why, but even the VCL isn't perfect. ;) OnDestroy should
>be a good place.
There's a bug in the VCL regarding TUpdateSQL datasets. If you set the
connection, say, in TQuery.UpdateObject, then the VCL does all the
right things on destroy. That is, it finds the UpdateObject and deals
with it properly. But if you set the connection in TUpdateSQL.Dataset,
the VCL doesn't check for that properly. If it then destroys the
TQuery first, it tries to destroy the TQuery again when it sees the
reference in TUpdateSQL and that's an access violation. You could
manage this by setting the creation order of the components, but I
find it easier to reset the TUpdateSQL.Dataset property in the data
module's destroy method.
Quote
>> 2. Because the "Dataset" is a join, then Delphi will think that all
>> changes to the underlying tables are modifications only. [snip]
>> But if an UpdateSQL table change can be an insert or a delete, then
>> you must write some code in the Dataset's OnUpdateRecord event. That
>> event will always start with ukModify (because of the join).
>Not what I'm seeing!
And you are right. My explanation was too simple. You can still get
inserts and deletes, but consider this:
Suppose you join two tables this way: Table A left join TableB. What
you get is a dataset that thinks that it's fully populated. You can
insert and delete and OnUpdateRecord will show insert or delete.
But suppose that all you do is to change a value in one field from
TableB. Given the way you joined the tables, there may be a TableB
record and there may not. The database will actually create a dummy
record of all nulls if it can't find a matching TableB record.
But cached updates doesn't know this. All it can see is a record with
nulls in it. When you change a TableB value, you will always get a
ukModify in OnUpdateRecord. In OnUpdateRecord, you have to test the
OldValue on the key fields of TableB to check if the record actually
exists. If the OldValues of the key fields are Null, then you must 1)
populate those fields and 2) use TUpdateSQL.Apply(ukInsert).
Otherwise, you can accept the ukModify and proceed normally.
Phil Cain
--