Page 1 of 1
roAfterUpdate - how?
Posted: Wed 09 Sep 2020 09:43
by malmedin
I set
IBCQuery.RefreshOptions := [roAfterUpdate];
to refresh record after update.
I was expected that this code
IBCQuery.Edit;
IBCQuery.FieldByName(SomeField).AsInteger := 1;
IBCQuery.Post;
calls
IBCQuery.RefreshRecord
but, it doesn't.
Am I missing something?
Re: roAfterUpdate - how?
Posted: Fri 18 Sep 2020 15:18
by ViktorV
When calling the RefreshRecord method, the query specified in the SQLRefresh property will be executed. If the SQLRefresh property is empty, IBDAC will automatically generate an SQL query when the RefreshRecord method is executed. If you manually set the SQLRefresh property to the required query, it will be executed when the RefreshRecord method is called.
When you execute the above code, the corresponding request is executed, you can verify this using the dbMonitor tool.
Note that you can use dbMonitor to find out what information is sent to the server, as well as when it is sent.
Re: roAfterUpdate - how?
Posted: Fri 18 Sep 2020 18:24
by malmedin
I was aware of everything you said, so I created sample project from scratch and it worked! I compared it to the project where it doesn't work and found out that roAfterUpdate has no effect if DMLRefresh is set to true. Help has a note saying that RefreshOptions
should be set to false when DMLRefresh is set to true to avoid rereading fields from server. It doesn't say anythig about RefreshOptions beeing disabled when DMLRefresh is set to true.
I consider it a bug because DMLRefresh is needed for getting field values set by trigger and RefreshOptions is needed for getting field values from joined tables.
Example
Tables
Code: Select all
CREATE TABLE PARENTS
(
ID INTEGER NOT NULL,
NAME VARCHAR(30)
);
CREATE TABLE CHILDREN
(
ID INTEGER NOT NULL, // field value is set by trigger
PARENTID INTEGER,
NAME VARCHAR(30)
);
Query.SQL
Code: Select all
SELECT c.ID, c.NAME, c.PARENTID, p.NAME
FROM CHILDREN c
JOIN PARENTS p ON p.ID = c.PARENTID
Query.SQLRefresh
Code: Select all
SELECT c.ID, c.NAME, c.PARENTID, p.NAME
FROM CHILDREN c
JOIN PARENTS p ON p.ID = c.PARENTID
WHERE c.ID = :ID
After insert in table CHILDREN, DMLRefresh (if set to true) is used to get ID.
After edit (and insert too) RefreshRecord (if roAfterUpdate and roAfterInsert are set to true) is used to get p.NAME.
But, they don't work together.
Re: roAfterUpdate - how?
Posted: Tue 22 Sep 2020 14:38
by ViktorV
This is the correct behavior for our components. When DMLRefresh is True the request you specified will not be executed:
https://www.devart.com/ibdac/docs/devar ... efresh.htm
But you can manually run TIBCQuery.RefreshRecord method to solve your issue.
Re: roAfterUpdate - how?
Posted: Wed 23 Sep 2020 10:46
by malmedin
ViktorV, thank you for the answer, but as you can see in the link you posted, it says
When DMLRefresh property is set to True, TCustomDADataSet.RefreshOptions should be set to False to avoid rereading fields' values from the server.
It is implied that both can be set to true.
Is it possible to make it function as described in help and let users decide whether they want "rereading fields' values from the server"?
Re: roAfterUpdate - how?
Posted: Fri 25 Sep 2020 11:16
by ViktorV
No, these queries won't be executed if DMLRefresh is enabled. We'll make changes to our documentation to remove ambiguity.