You can create a DML trigger on a table or a view. A triggering event consists of the DELETE, INSERT, and UPDATE DML statements.
Unlike stored procedures and packages, a trigger has a separate namespace. Therefore, the name of a trigger can be identical to the name of a table or stored procedure. You must have the CREATE TRIGGER system privilege to create triggers.
Create a row-level trigger
The current version of OceanBase Database supports the following types of row-level triggers:
BEFORE INSERT FOR EACH ROWAFTER INSERT FOR EACH ROWBEFORE UPDATE FOR EACH ROWAFTER UPDATE FOR EACH ROWBEFORE DELETE FOR EACH ROWAFTER DELETE FOR EACH ROW
The syntax for creating a row-level trigger is as follows:
CREATE [OR REPLACE] TRIGGER trigger_name
{BEFORE | AFTER }
{INSERT | DELETE | UPDATE [OF column [, column ...]]}
ON [schema.] table_name
[REFERENCING {OLD [AS] old | NEW [AS] new| PARENT as parent}]
FOR EACH ROW
[{ FOLLOWS | PRECEDES } other_trigger_name]
[WHEN condition]
BEGIN
...
END;
The following table describes the parameters in the syntax.
| Parameter | Definition | Description |
|---|---|---|
BEFORE or AFTER |
Specifies whether the trigger is activated before or after the triggering event. | A BEFORE trigger is activated before the triggering event is executed. An AFTER trigger is activated after the triggering event is executed. |
FOR EACH ROW |
Specifies the trigger as a row-level trigger. | If a DML statement affects multiple rows of data in a table, the row-level trigger is activated for each row provided that the rows meet the trigger condition. |
REFERENCING |
Specifies the correlation name. The correlation name can be used to reference the current new and old column values in the Procedural Language (PL) block and WHEN clause of the row-level trigger. The default correlation names are OLD and NEW. |
When you use the correlation names in the PL block of the trigger, you must add a colon (:) before them. In the WHEN clause, you must not add the colon (:). |
WHEN |
Specifies the trigger condition. | If the condition is a logical expression, it must contain the correlation name, and cannot contain a query statement or call a PL function. You can use the WHEN clause to specify a trigger condition only for row-level BEFORE and AFTER triggers. |
FOLLOWS or PRECEDES |
Specifies the order of triggers. | OceanBase Database allows you to associate multiple triggers of the same triggering event and activating time to the same table. By default, triggers with the same triggering event and activating time are activated in a random order. You can specify FOLLOWS, so that a new trigger is activated after the current trigger. At present, you can specify PRECEDES, which means that a new trigger is activated before the current trigger, but the configuration does not take effect. |
Notice
When an INSERT, UPDATE, or DELETE operation is performed on a base table, the corresponding stored procedure must be executed by the application. However, a trigger associated with the base table automatically is activated upon any DML operation on the table, which is irrelevant to the application, to ensure data consistency and integrity.
Limitations on row-level triggers
When you use row-level triggers, note that:
The
SELECTstatement in a row-level trigger must use theSELECT ... INTO ...syntax, or be theSELECTstatement used to define a cursor.You cannot use transaction control statements, such as
COMMIT,ROLLBACK, andSAVEPOINT, in a row-level trigger.A stored procedure or function called by a row-level trigger cannot contain transaction control statements either.
OLD and NEW pseudorecords
When a row-level trigger is executed, it may reference the values of a column before or after an INSERT, UPDATE, or DELETE operation.
:NEWindicates the value of a column after an operation.:OLDindicates the value of a column before an operation.
The following table lists the validity of NEW and OLD records in different operations.
| Feature | INSERT | UPDATE | DELETE |
|---|---|---|---|
| OLD | NULL | Valid | Valid |
| NEW | Valid | Valid | NULL |
Example
Create a simple row-level trigger.
obclient> CREATE TABLE regions(
region_id NUMBER(5,0),
region_name VARCHAR(50)
);
Query OK, 0 rows affected
obclient>INSERT INTO regions VALUES(1,'Europe'),(4,'Middle East and Africa'),(3,'Asia'),
(2,'Americas');
Query OK, 4 rows affected
obclient> CREATE TABLE reg_his AS SELECT * FROM regions WHERE 1=2;
Query OK, 0 rows affected
obclient> CREATE OR REPLACE TRIGGER del_new_region
BEFORE DELETE ON regions
FOR EACH ROW
WHEN (old.region_id >3)
BEGIN
INSERT INTO reg_his(region_id , region_name )
VALUES( :old.region_id, :old.region_name );
END;
/
Query OK, 0 rows affected
In the preceding example, when data is dropped from the regions table, records with a region_id value greater than 3 are moved to the reg_his table.
obclient>SELECT * FROM regions;
+-----------+------------------------+
| REGION_ID | REGION_NAME |
+-----------+------------------------+
| 1 | Europe |
| 4 | Middle East and Africa |
| 3 | Asia |
| 2 | Americas |
+-----------+------------------------+
4 rows in set (0.00 sec)
obclient>SELECT * FROM reg_his;
Empty set
obclient> DELETE FROM regions WHERE region_id>2;
Query OK, 2 rows affected
obclient> SELECT * FROM regions;
+-----------+-------------+
| REGION_ID | REGION_NAME |
+-----------+-------------+
| 1 | Europe |
| 2 | Americas |
+-----------+-------------+
2 rows in set
obclient> SELECT * FROM reg_his;
+-----------+------------------------+
| REGION_ID | REGION_NAME |
+-----------+------------------------+
| 4 | Middle East and Africa |
+-----------+------------------------+
1 row in set
Create a statement-level trigger
A statement-level trigger is also a table-level trigger. A statement-level trigger is activated once when a specified statement is executed. In other words, the statement operation is a triggering event. If you create a statement-level trigger for a DML operation on a table, the system automatically executes the statement specified in the trigger when the DML operation is executed.
The syntax for creating a statement-level trigger is as follows:
CREATE [OR REPLACE] TRIGGER trigger_name
{BEFORE | AFTER }
{INSERT | DELETE | UPDATE [OF column [, column ...]]}
ON [schema.] table_name
BEGIN
...
END;
Limitations on statement-level triggers
A statement-level trigger cannot access data before or after an operation by using the
OLDorNEWkeyword.A
WHENclause cannot be specified in a statement-level trigger.
Example
Create a table to record the deleted data of a new table.
Create a table named
studentand a table namedold_student, and then use theold_studenttable to record the deleted data of thestudenttable.obclient> CREATE TABLE student( id VARCHAR2(4) NOT NULL, name VARCHAR2(15) NOT NULL, age NUMBER(2) NOT NULL, sex VARCHAR2(15) NOT NULL ); Query OK, 0 rows affected obclient> CREATE TABLE old_student AS SELECT * FROM student; Query OK, 0 rows affected obclient> INSERT INTO student VALUES('01','a',6,'Male'),('02','b',7,'Female'); Query OK, 2 rows affected obclient> SELECT * FROM student; +----+------+-----+--------+ | ID | NAME | AGE | SEX | +----+------+-----+--------+ | 01 | a | 6 | Male | | 02 | b | 7 | Female | +----+------+-----+--------+ 2 rows in set obclient> SELECT * FROM old_student; Empty setCreate a statement-level
TIG_OLD_STUtrigger.obclient> delimiter / obclient> CREATE OR REPLACE TRIGGER TIG_OLD_STU BEFORE DELETE ON student BEGIN INSERT INTO old_student SELECT * FROM student; END; / Query OK, 0 rows affected obclient> delimiter;Delete the data in the
studenttable, and view the data of the two tables.obclient> DELETE student; Query OK, 0 rows affected obclient> SELECT * FROM student; Empty set obclient> SELECT * FROM old_student; +----+------+-----+--------+ | ID | NAME | AGE | SEX | +----+------+-----+--------+ | 01 | a | 6 | Male | | 02 | b | 7 | Female | +----+------+-----+--------+ 2 rows in set