1 Introduction
A trigger is a type of stored procedure that is executed when trying to modify data in a table or view. They are created to preserve referential integrity and consistency amongst data between different tables. If you try to modify (insert, update or delete) data from a table or view in which a trigger was defined for any of these actions (insert, update and delete), the trigger is automatically executed. A trigger is associated with an event (insert, update or delete) on a table.
Triggers are written in SQL and compiled into the database through the CREATE TRIGGER command. Some examples of the use of triggers may be:
- Before registering a new sales order for a customer, it checks if he has a pending debt; in this case it cancels the registration of that order stating the reason.
- Removing a provider from our database involves deleting all data related to that provider.
- Updating the total amount of an invoice each time a detail line is inserted, deleted or updated.
2 XSQL-trigger
Axional Studio
XSQL-Trigger is an XML grammar developed by Deister Software, which allows you to implement triggers in XML code.
This way, it is possible to automatically transform them into the native syntax of the different database agents supported by Axional Studio
.
<xsql-trigger
name='name'
table='table'
event='insert|update|delete|instead-of-insert|instead-of-update|instead-of-delete'
of='columns'
>
<if-engine type='ids|iwa|oracle|db2i|db2u|postgres|sqlserver|mysql|access|universe|cloudscape'> *
<before> ?
<[xsql-block-body]> *
</before>
<foreach-row> ?
<[xsql-block-body]> *
</foreach-row>
<after> ?
<[xsql-block-body]> *
</after>
</if-engine>
<if-not-engine type='ids|iwa|oracle|db2i|db2u|postgres|sqlserver|mysql|access|universe|cloudscape'> *
<before> ?
<[xsql-block-body]> *
</before>
<foreach-row> ?
<[xsql-block-body]> *
</foreach-row>
<after> ?
<[xsql-block-body]> *
</after>
</if-not-engine>
<before> ?
<[xsql-block-body]> *
</before>
<foreach-row> ?
<[xsql-block-body]> *
</foreach-row>
<after> ?
<[xsql-block-body]> *
</after>
</xsql-trigger>
Attributes | |||||
---|---|---|---|---|---|
Name | Type | Required | Default | Description | |
Aname | string | Trigger name | |||
Atable | string | Application table or view | |||
Aevent | string | Type of DML statement that causes activation.
|
|||
Aof | string | Columns that have to be modified for the trigger to be executed. This is valid for the triggers for updating. If column/s are indicated, the trigger will only be executed when any column of the list is updated. |
Arguments | |||||
---|---|---|---|---|---|
Name | Type | Required | Unique | Nullable | Description |
Eif-engine | The XML grammar for TRIGGERS has been developed to be able to write a trigger only once and to be used
independently of the database agent used (IBM-IDS, Oracle, DB2 ...).
However, sometimes and due to the complexity of unifying some statements,
it is necessary to indicate differentiated blocks for each of the agents used from Axional Studio .
If the database agent used is the one indicated in the type attribute,
the content inside this element is transformed. Otherwise, the content is ignored. |
||||
Atype | String | Database agent used. | |||
Ebefore | Within this block there are indicated the statements that are executed before performing any insert, update or delete operation on the rows affected by the trigger. In other words, BEFORE STATEMENT is executed, only once before the set of rows affected by the trigger. | ||||
V[xsql-block-body] | Within the xsql-block-body section, several statements can be concatenated XML-DML (insert, delete, update, execute-funcion, execute-procedure, nativesql), that will be executed each time the trigger occurs or when a Boolean expression is met within the tag "when". | ||||
Eforeach-row | Within this block the statements that affect each of the rows are indicated independently. | ||||
V[xsql-block-body] | Within the xsql-block-body section, several statements can be concatenated XML-DML (insert, delete, update, execute-funcion, execute-procedure, nativesql), that will be executed each time the trigger occurs or when a Boolean expression is met within the tag "when". | ||||
Eafter | Within this block there are indicated the statements that must be executed after performing any insert, update or delete operation on the rows that have been affected by the trigger. That is to say, they are executed AFTER STATEMENT, only once after the set of rows affected by the trigger. | ||||
V[xsql-block-body] | Within the xsql-block-body section, several statements can be concatenated XML-DML (insert, delete, update, execute-funcion, execute-procedure, nativesql), that will be executed each time the trigger occurs or when a Boolean expression is met within the tag "when". | ||||
Eif-not-engine | This is the opposite case to the if-engine element. The block of statements included in this element is only ignored in the database engine indicated in the attribute type . | ||||
Atype | String | Database agent used. | |||
Ebefore | Within this block there are indicated the statements that are executed before performing any insert, update or delete operation on the rows affected by the trigger. In other words, they are executed BEFORE STATEMENT, only once before the set of rows affected by the trigger. | ||||
V[xsql-block-body] | Within the xsql-block-body section, several statements can be concatenated XML-DML (insert, delete, update, execute-funcion, execute-procedure, nativesql), that will be executed each time the trigger occurs or when a Boolean expression is met within the tag "when". | ||||
Eforeach-row | Within this block the statements that affect each of the rows are indicated independently. | ||||
V[xsql-block-body] | Within the xsql-block-body section, several statements can be concatenated XML-DML (insert, delete, update, execute-funcion, execute-procedure, nativesql), that will be executed each time the trigger occurs or when a Boolean expression is met within the tag "when". | ||||
Eafter | Within this block there are indicated the statements that are executed after performing any insert, update or delete operation on the rows affected by the trigger. That is to say, they are executed AFTER STATEMENT, only once after the set of rows affected by the trigger. | ||||
V[xsql-block-body] | Within the xsql-block-body section, several statements can be concatenated XML-DML (insert, delete, update, execute-funcion, execute-procedure, nativesql), that will be executed each time the trigger occurs or when a Boolean expression is met within the tag "when". | ||||
Ebefore | Within this block there are indicated the statements that are executed before performing any insert, update or delete operation on the rows affected by the trigger. In other words, they are executed BEFORE STATEMENT, only once before the set of rows affected by the trigger. | ||||
V[xsql-block-body] | Within the xsql-block-body section, several statements can be concatenated XML-DML (insert, delete, update, execute-funcion, execute-procedure, nativesql), that will be executed each time the trigger occurs or when a Boolean expression is met within the tag "when". | ||||
Eforeach-row | Within this block the statements that affect each of the rows are indicated independently. | ||||
V[xsql-block-body] | Within the xsql-block-body section, several statements can be concatenated XML-DML (insert, delete, update, execute-funcion, execute-procedure, nativesql), that will be executed each time the trigger occurs or when a Boolean expression is met within the tag "when". | ||||
Eafter | Within this block there are indicated the statements that are executed after performing any insert, update or delete operation on the rows affected by the trigger. That is to say, they are executed AFTER STATEMENT, only once after the set of rows affected by the trigger. | ||||
V[xsql-block-body] | Within the xsql-block-body section, several statements can be concatenated XML-DML (insert, delete, update, execute-funcion, execute-procedure, nativesql), that will be executed each time the trigger occurs or when a Boolean expression is met within the tag "when". |
3 Trigger body
The trigger body includes up to three distinct blocks:
- before: statements that are executed only once before performing any insert, update or delete operation on the set of rows affected by the trigger.
- foreach-row: statements that affect each of the rows independently and that will be executed after the event (insert, delete, update) on the lines.
- after: statements that are executed only once after performing any insert, update, or delete operation on the set of rows affected by the trigger.
The general structure of a trigger would be the following, where each of the blocks is optional:
<xsql-trigger name='disparador1' event='insert|update|delete|instead-of-insert|instead-of-update|instead-of-delete' of='columns' table='table' > <before> [xsql-block-body] </before> <foreach-row> [xsql-block-body] </foreach-row> <after> [xsql-block-body] </after> </xsql-trigger>
[xsql-block-body]:
[<when><expr>expression</expr><then>[xsql-statement]</then></when>] [xsql-statement]
3.1 TAG nxt
This element is used to refer to the new value of the column that contains inside. It is used in the update and insert events.
<nxt>
<column /> !
</nxt>
Arguments | |||||
---|---|---|---|---|---|
Name | Type | Required | Unique | Nullable | Description |
Ecolumn | null | Column name that must belong to the table for which the trigger is created. |
3.2 TAG prv
This element is used to refer to the old value of the column that contains inside. It is used in the update and delete events.
<prv>
<column /> !
</prv>
Arguments | |||||
---|---|---|---|---|---|
Name | Type | Required | Unique | Nullable | Description |
Ecolumn | null | Column name that must belong to the table for which the trigger is created. |
3.3 TAG when
This element serves to express conditional statements.
<when mutating='yes|y'>
<expr> !
<SQL Boolean Condition /> *
<expr-select /> *
<try /> *
</expr>
<then /> !
</when>
Attributes | |||||
---|---|---|---|---|---|
Name | Type | Required | Default | Description | |
Amutating | boolean | Indicates that an attempt is made to access a table that is being mutated, that is, it is being modified by the trigger or by the event that executed the trigger. |
Arguments | |||||
---|---|---|---|---|---|
Name | Type | Required | Unique | Nullable | Description |
Eexpr | null | It is a required argument that must be located immediately after the element "when" and that is where the conditional statement will be written. | |||
ESQL Boolean Condition | null | Boolean condition written in SQL syntax. | |||
Eexpr-select | null | Select statement | |||
Etry | null | Try statement for error capture. | |||
Ethen | null | Within this element the statements to be executed are included if the condition is met. |
The following example shows how to execute an SQL statement, in this case a function only when the value entered in the docser column ends with a '-'.
<when> <expr> <nxt>docser</nxt> <matches>'*-'</matches> </expr> <then> <execute-function name='eh_cvenfach_nxt_docser' into='docser'> <nxt>facidx</nxt>,<nxt>docser</nxt> </execute-function> </then> </when>
3.4 TAG expr-select
Generally it allows to express an SQL query to the database that returns a single value.
<expr-select>
<SELECT SQL Code /> *
<expr-into type='type' /> *
</expr-select>
Arguments | |||||
---|---|---|---|---|---|
Name | Type | Required | Unique | Nullable | Description |
ESELECT SQL Code | null | SQL code of the SELECT to perform. | |||
Eexpr-into | null | This element is used to indicate the type of data returned by SELECT (required in Oracle). | |||
Atype | null | It is necessary to indicate the type of data to be returned in the SELECT: integer, char, varchar, etc .; nombre_table.nomre_columna%TYPE: if type is unknown, it can be indicated from which table and which column the system should take the type of data returned by SELECT. |
Application of use for the expr-select element in a conditional statement when, as may be seen, just above the FROM statement, the type of data of the query result has been indicated. The rest of the statements are SQL, except for the use of the <nxt> which serves to indicate the new value of the field that contains it after the execution of the trigger that was launched by the insert or update event.
<when> <expr> <expr-select> SELECT COUNT(*) <expr-into type='integer' FROM cprodefl WHERE cprodefl.procod = <nxt>procod</nxt> </expr-select> > 1 </expr> <then> .... </then> </when>
4 DML Trigger
One or more statements can be concatenated within the trigger body SQL-DML which are executed consecutively each time the trigger is executed or when a boolean expression, indicated within the tag when, is met.
- Check the grammar XSQL for an insert statement by following this link XSQL-INSERT
- Check the grammar XSQL for an update statement by following this link XSQL-UPDATE
- Check the grammar XSQL for an delete statement by following this link XSQL-DELETE
- Check the grammar XSQL for an execute-procedure statement by following this link XSQL-EXECUTE-PROCEDURE
- Check the grammar XSQL for an execute-function statement by following this link XSQL-EXECUTE-FUNCTION