Relations are Forms internal objects that are created
The default behavior of a master-detail relation is as follows :
These implicit actions are controlled by certain properties of a relation, which are
The first behavior is controlled by the Co-ordination property, the second by the Copy Value From Item property of the foreign key item in the detail block, and the third partly by the Copy Value From Item property and partly by the Master-Deletes property of a relation.
The techniques given in this section pertain to the following:
Suppressing Master-Detail Behavior
Suppressing master-detail behavior is a requirement when searching through the master block based on an item value. To speed the search process, it is worthwhile to suppress the automatic query of the detail block for every master record temporarily for the duration of the search.
You can do this by changing the master-detail relation properties dynamically before starting the search and by resetting them after the search is complete. The automatic clearing and querying of the detail block for every new master record are by means of the ON-CLEAR-DETAILS trigger at the form level and the ON-POPULATE-DETAILS trigger at the master-block level. This is due to the default Immediate coordination taking place when the master record changes. The firing of these two triggers can be suppressed by changing the Immediate coordination to Deferred with Auto-Query.
In the appropriate trigger, set the AUTOQUERY and DEFERRED_COORDINATION properties for the relation involved to TRUE before looping through the master block, and reset both of them to FALSE after the find is over. This delays the query of the detail block until the user does an explicit EXECUTE_QUERY and thus prevents automatic population of the detail block for every master record. The code involved is similar to the following:
WHEN-BUTTON-PRESSED trigger of search button. DECLARE relation_id Relation; BEGIN /* Find the relation id corresponding to the relation name. If the resulting ID is NULL, the given relation is invalid. Otherwise, set its properties to DEFERRED with AUTOQUERY */ relation_id := Find_Relation(); IF NOT Id_Null(relation_id) THEN SET_RELATION_PROPERTY(relation_id, AUTOQUERY, PROPERTY_TRUE); SET_RELATION_PROPERTY(relation_id, DEFERRED_COORDINATION, PROPERTY_TRUE); ELSE MESSAGE('InvalidRelation'); RAISE FORM_TRIGGER_FAILURE; END IF; /* Proceed with the search operation */
/* RE-query the detail block to ensure that it gets populated after the search. This is required because no automatic query of the detail block takes place due to DEFERRED coordination. */ GO_BLOCK(); EXECUTE_QUERY; GO_BLOCK(); /* Reset the relation properties after the search is complete */ SET_RELATION_PROPERTY(relation_id, AUTOQUERY, PROPERTY_FALSE); SET_RELATION_PROPERTY(relation_id, DEFERRED_COORDINATION, PROPERTY_FALSE); END;
The EXECUTE_QUERY for the detail block is necessary; otherwise, the detail block is left empty after the search is over.
Toggling Between Immediate and Deferred Coordination
This section presents a technique to toggle between immediate and deferred coordination. This is very useful in situations like the search operation discussed above. Before the search process, you switch to deferred coordination from the default immediate coordination. After the search is over, you can toggle back to immediate coordination.
You can toggle between the IMMEDIATE and DEFERRED coordination by dynamically changing the relation's Coordination property. To do so, you change the master-detail relation DEFERRED_COORDINATION property dynamically to the opposite of the current setting. The AUTOQUERY property has to be reset to TRUE if automatic requery is necessary after DEFERRED coordination is turned on. It is turned off automatically because of the cascading effect of DEFERRED coordination. This method can be implemented as a procedure p_toggle_ coordination given below. You can use code like the following in the actual trigger to make a call to the above mentioned procedure:
WHEN-BUTTON-PRESSED DECLARE v_retcd NUMBER; v_errm VARCHAR2(100); BEGIN -- Call the togglre procedure before the search p_toggle_coordination(, v_retcd, v_errm); IF (v_retcd <> 0) THEN MESSAGE(v_errm); RAISE FORM_TRIGGER_FAILURE; END IF; -- Search process -- Call the toggle procedure after the search END;
The code for the procedure p_toggle_coordination is given below:
PROCEDURE p_toggle_coordination(p_relation_name IN VARCHAR2, retcd OUT NUMBER, errm OUT VARCHAR2) IS relation_id RELATION; BEGIN relation_id := FIND_RELATION(p_relation_name); IF NOT Id_Null(relation_id) THEN IF GET_RELATION_PROPERTY(relation_id, DEERRED_COORDINATION) = 'FALSE' THEN SET_RELATION_PROPERTY(relation_id, DEFERRED_COORDINATION, PROPERTY_TRUE); ELSE SET_RELATION_PROPERTY(relation_id, DEFERRED_COORDINATION, PROPERTY_FALSE); END IF; IF FORM_SUCCESS THEN retcd := 0; ELSE retcd := -1; errm := 'Toggle Relation Failure'; ELSE retcd := -1; errm := 'Invalid Relation'; END IF; END p_toggle_coordination;
Advanced GUI Development: Developing Beyond GUI
Advanced Forms Programming
Object-oriented Methods in Forms
Intelligence in Forms
Additional Interesting Techniques
Working with Trees
Oracle 8 and 8i Features in Forms Developer