RDB/VMS Relational Database Operator DEFINE_TRIGGER — VMS RDB_4.0B
Creates a trigger for the specified relation. A trigger is a mechanism which associates a set of rules with an update operation. Example: RDO> DEFINE TRIGGER EMPLOYEE_ID_CASCADE_DELETE <--- trigger name cont> BEFORE ERASE <--- action time cont> FOR E IN EMPLOYEES <--- subject relation cont> EXECUTE cont> FOR D IN DEGREES WITH <--- triggered action rse cont> D.EMPLOYEE_ID = E.EMPLOYEE_ID cont> ERASE D <--- triggered action cont> END_FOR; cont> FOR EACH RECORD. <--- frequency clause
Additional information available:
More
To define a trigger, you need the Rdb/VMS READ and DEFINE privileges to the subject relation. If any triggered statement specifies some form of update operation, then CONTROL and the appropriate update privilege (ERASE, MODIFY, or WRITE) to the relations specified by the triggered action statements are also required. Each trigger is associated with a single subject relation, will be evaluated at a specific time for a particular type of update on that relation, and specifies a series of 'triggered' actions. Each triggered action consists of an optional condition and one or more statements to be evaluated either once only or for each record of the relation being updated. You can use triggers with relation-specific constraints to preserve database integrity. You can define a trigger only after you have invoked the database. See the DEFINE_RELATION statement. You must execute this statement in a read/write transaction. If there is no active transaction and you issue this statement, Rdb/VMS starts a read/write transaction implicitly. Other users are allowed to be attached to the database when you issue the DEFINE TRIGGER statement.
Format
DEFINE TRIGGER ─> name ┬──────────────>─────────────┬┬─>
B
E
F
O
R
E ┬┐ └>
D
E
S
C
R
I
P
T
I
O
N typebox (I)typebox (S) typebox (/)typebox (*) text */ ┘└─>
A
F
T
E
R ─┘│ ┌─────────────────────────────<──────────────────────────────────┘ └┬>
S
T
O
R
E ───────────────────>──────────────────────────────────┬┐ ├>
E
R
A
S
E ───────────────────>──────────────────────────────────┤│ └>
M
O
D
I
F
Y ┬──────────>──────────┬┬──────────────>────────────┬─┘│ └>
O
F ─┬> field-name ┬┘└> context-variable-clause ─┘ │ └───── , <────┘ │ ┌──────────────────────────────────<─────────────────────────────┘ └>
F
O
R context-var IN relation-name ┬> triggered-action-clause ┬> . └──────────────<───────────┘
Additional information available:
nametextfield-namecontext-variable-clausecontext-varrelation-name
triggered-action-clause
name
The name of the trigger that you can refer to in other statements. Use a name that is unique among all trigger names.
text
A text string that adds a comment to the trigger definition.
field-name
The name of a field within the specified relation to be checked for modification. You can specify a list of field names separated by commas. You can also specify all the fields in a relation by specifying the asterisk (*) wildcard character. Be sure that you specify ONLY those fields whose data values are to be changed. See the subtopic More for more information.
Additional information available:
More
In a BEFORE MODIFY or AFTER MODIFY trigger, be sure that you specify
only the names of fields whose data values are to be changed, to
avoid potentially unnecessary actions such as:
o Overlaying the data with itself within a record.
o Writing to the database (even though none of the fields in the
record has actually changed values)
o Evaluating constraints that apply to fields in the MODIFY field
list which have not changed values
o Evaluating MODIFY triggers that apply to fields in the MODIFY
field list that have not changed values.
o Evaluating RDO VALID IF clauses for fields in the MODIFY field
list that have not changed values.
If there is a possibility that any of the fields in a MODIFY field
list will not actually be changed, the triggered actions for any
pertinent MODIFY triggers should be changed accordingly.
For those cases in which a triggered action performs an operation
based on the changed value for a particular field, the action should
include a conditional expression that prevents execution of the
operation if no value change occurs. The conditional expression,
which compares the old value with the new value, should appear as
part of the triggered action's WITH clause.
context-variable-clause
context-variable-clause = ──┬────────────────────────────────┬─> ├─>
O
L
D typebox (C)typebox (O)typebox (N)typebox (T)typebox (E)Xtypebox (T) old-context-var ─┤ └─>
N
E
W typebox (C)typebox (O)typebox (N)typebox (T)typebox (E)Xtypebox (T) new-context-var ─┘ An optional clause that can contain aliases for old and new states of the context variable of the triggering statement.
Additional information available:
old-context-varnew-context-var
old-context-var
A temporary name used to refer to the record values as they existed before a modify operation occurred. You use an old-context-var only when the trigger occurs after a modify operation, and must be a different name than the one given for context_var.
new-context-var
A temporary name used to reference the new record values about to be applied by modify operation. You use a new-context-var only when the trigger occurs before a modify operation, and must be a different name than the one given for context-var.
context-var
A temporary name defining the relation on which the trigger is defined. The context variable name is an alias for the record stream context of the triggering statement which has caused this trigger to be executed.
relation-name
The name of the relation for which this trigger is defined (subject relation).
triggered-action-clause
triggered-action-clause = ─┬───────────────────────────┬─┐ └─>
W
I
T
H conditional-expr ──┘ │ ┌─────────────────────────────┘ └─>
E
X
E
C
U
T
E ─┬> triggered-statement ─┬──┬───────────────────┬─> └─────────── typebox (;) ────<────┘ └─>
F
O
R
E
A
C
H
R
E
C
O
R
D ┘ triggered-statement = ─┬─> store-statement ───────────────────┬─> ├─>
F
O
R rse store-statement ENDFOR ──┤ ├─>
F
O
R rse erase-statement ENDFOR ──┤ ├─>
F
O
R rse modify-statement ENDFOR ──┤ └─>
E
R
R
O
R ─────────────────────────────┘ A triggered action clause consists of a conditional expression (optional), one or more triggered statements, and a frequency clause (FOR EACH RECORD). The EXECUTE keyword precedes the triggered action clause.
Additional information available:
rsestore-statementerase-statementmodify-statement
rse
A record selection expression that defines which records of which relations will be affected by the triggered update action. This rse cannot refer to any host variables.
store-statement
A STORE statement to be initiated by the trigger.
erase-statement
An ERASE statement to be initiated by the trigger.
modify-statement
A MODIFY statement to be initiated by the trigger.
WITH
A conditional expression that describes the optional condition that must be satisfied before the associated triggered statements are executed. This expression cannot refer to any host variables. For more information on Rdb/VMS conditional expressions, ask for HELP on the top level topic Cond_expr.
FOR_EACH_RECORD
A frequency clause, FOR EACH RECORD (no underscores), determines whether an action is evaluated once per triggering statement, or for each record of the subject relation updated by the triggering statement. If the FOR EACH RECORD clause is not specified, the triggered action is evaluated only once, and record values are not available to the triggered action.
Examples
The following example defines a trigger that performs a cascading
delete triggered by the deletion of an employee record. Such a
trigger can be used to maintain referential integrity among the
EMPLOYEES, JOB_HISTORY, RESUMES, and SALARY_HISTORY relations.
Each associated employee record (from the relations which have
foreign keys referring to the primary key in the EMPLOYEES relation)
is deleted.
RDO> DEFINE TRIGGER EMPLOYEE_ID_CASCADE_DELETE
cont> BEFORE ERASE
cont> FOR E IN EMPLOYEES
cont> EXECUTE
cont> FOR D IN DEGREES WITH
cont> D.EMPLOYEE_ID = E.EMPLOYEE_ID
cont> ERASE D
cont> END_FOR;
cont> FOR JH IN JOB_HISTORY WITH
cont> JH.EMPLOYEE_ID = E.EMPLOYEE_ID
cont> ERASE JH
cont> END_FOR;
cont> FOR R IN RESUMES WITH
cont> R.EMPLOYEE_ID = E.EMPLOYEE_ID
cont> ERASE R
cont> END_FOR;
cont> FOR SH IN SALARY_HISTORY WITH
cont> SH.EMPLOYEE_ID = E.EMPLOYEE_ID
cont> ERASE SH
cont> END_FOR
cont> FOR EACH RECORD.
The following RDO command procedure example defines a MODIFY trigger
with two actions. The first action is defined to account for the
situation where the triggering MODIFY statement has not actually
changed the value for the pertinent field (EMPLOYEE_ID). This
trigger causes a cascading update of the EMPLOYEES relation's
EMPLOYEE_ID value to the JOB_HISTORY table. The WITH clause
stipulates that the cascading update will occur only when the
EMPLOYEE_ID value actually changes. The example also logs each
MODIFY operation to the LOG relation.
!
! Invoke the database:
INVOKE DATABASE FILENAME 'PERSONNEL'
!
! Define the global fields for the LOG relation:
START_TRANSACTION READ_WRITE
!
DEFINE FIELD TYPE
DATATYPE IS TEXT 10.
%RDO-W-NOCDDUPDAT, database invoked by filename, the CDD will not be
updated
!
DEFINE FIELD REL_NAME
DATATYPE IS TEXT 31.
!
! Define the LOG relation:
DEFINE RELATION LOG.
TYPE.
REL_NAME.
END LOG RELATION.
!
! Define trigger TRIG1:
DEFINE TRIGGER TRIG1
AFTER MODIFY OF EMPLOYEE_ID OLD CONTEXT OLD_EMP
FOR NEW_EMP IN EMPLOYEES
WITH NEW_EMP.EMPLOYEE_ID <> OLD_EMP.EMPLOYEE_ID EXECUTE
FOR JH IN JOB_HISTORY
WITH JH.EMPLOYEE_ID = OLD_EMP.EMPLOYEE_ID
MODIFY JH USING JH.EMPLOYEE_ID = NEW_EMP.EMPLOYEE_ID
END_MODIFY
END_FOR
FOR EACH RECORD
EXECUTE
STORE L IN LOG USING
L.TYPE = "Modify";
L.REL_NAME = "EMPLOYEES"
END_STORE
FOR EACH RECORD.
!
! Test the trigger by changing the EMPLOYEE_ID of "00164" to "98765":
FOR E IN EMPLOYEES WITH E.EMPLOYEE_ID = "00164"
MODIFY E USING E.EMPLOYEE_ID = "98765"
END_MODIFY
END_FOR
!
! The trigger causes a record to be stored in the LOG relation:
FOR L IN LOG
PRINT L.TYPE,
L.REL_NAME
END_FOR
TYPE REL_NAME
Modify EMPLOYEES
!