OraclePL/SQL trigger learning notes

Source: Internet
Author: User
A trigger is also a named PLSQL block. Triggers are similar to processes and functions, because they are all named PLSQL blocks with declarations, executions, and exception handling processes. Similar to the package,

A trigger is also a named PL/SQL block. Triggers are similar to processes and functions, because they are all named PL/SQL blocks with declarations, executions, and exception handling processes. Similar to the package,

1. Concepts of triggers

A trigger is also a named PL/SQL block. Triggers are similar to processes and functions, because they are all named PL/SQL blocks with declarations, executions, and exception handling processes. Similar to the package, triggers must be stored in the database and cannot be declared locally by blocks.

When a trigger event occurs, the trigger is executed explicitly, and the trigger does not accept parameters.

The syntax for creating a trigger is as follows:

View plaincopy to clipboardprint?

CREATE [or replace] TRIGGER trigger_name

{BEFORE | AFTER | instead of} triggering_event

[Referencing_clause]

[WHEN trigger_condition]

[For each row]

Trigger_body;

CREATE [or replace] TRIGGER trigger_name

{BEFORE | AFTER | instead of} triggering_event

[Referencing_clause]

[WHEN trigger_condition]

[For each row]

Trigger_body;

The referencing_clause uses a different name to reference data in the currently updated record row. Trigger_condition in the when clause-If yes, the trigger's Subject code will be executed only WHEN the condition value is true.

2. DML trigger activation sequence

1) execute the before statement-Level Trigger-if such trigger exists

2) records of each row affected by the statement

Execute the before row-Level Trigger-if this trigger exists

Execute the statement itself

Execute the after row-level trigger -- if such trigger exists

3) execute the after statement-level trigger -- if such trigger exists

The ignition sequence of the same type of trigger is not defined. If this order is important, we recommend that you combine all these operations into one trigger.

3. Association identifier in a row-Level Trigger

The row-Level Trigger is activated once every row of data is processed by the trigger activation statement. You can access the data in the record row being processed within this row-Level Trigger. This is achieved through two associated identifiers --: old and: new. The Association identifier is also a special binding variable of PL/SQL. The colon Before the identifier indicates that both are bound variables, and that they are not common PL/SQL variables. PL/SQL Compiler will regard them as the following types of records:

Triggering_table % ROWTYPE

Triggering_table is the name of the table on which the trigger is defined. Therefore, the following reference

: New. field

It is valid only when the field in the trigger table is the field name.

Trigger statement

: Old

: New

INSERT

Undefined-all fields are NULL

Value to be inserted when the trigger statement is complete

UPDATE

Update the original value of the corresponding record row

Value to be updated when the trigger statement is complete

DELETE

Delete the original value of the corresponding record row

Undefined-all fields are NULL

Note: the "old" identifier is not defined in the INSERT statement, and the "new" identifier is not defined in the DELETE statement. If you use the: old identifier in the INSERT statement or the: new identifier in the DELETE statement, PL/SQL does not produce errors, but the values of both fields are NULL.

Pseudo record

Although the syntax structure regards: new and: old as records of the triggering_table % ROWTYPE type, they are not actually records. Therefore, operations that can be normally performed on records cannot be executed on: new and: old. For example, you cannot assign values as a whole. You can only assign values to each field.

View plaincopy to clipboardprint?

Create or replace trigger TempDelete

Before delete on temp_table

FOR EACH ROW

DECLARE

V_TempRec temp_table % ROWTYPE;

BEGIN

/* This is not a legal assignment, since: old is not truly

A record .*/

V_TempRec: =: old;

/* We can accomplish the same thing, however, by assigning

The fields inpidually .*/

V_TempRec.char_col: =: old. char_col;

V_TempRec.num_col: =: old. num_col;

END TempDelete;

/

Create or replace trigger TempDelete

Before delete on temp_table

FOR EACH ROW

DECLARE

V_TempRec temp_table % ROWTYPE;

BEGIN

/* This is not a legal assignment, since: old is not truly

A record .*/

V_TempRec: =: old;

/* We can accomplish the same thing, however, by assigning

The fields inpidually .*/

V_TempRec.char_col: =: old. char_col;

V_TempRec.num_col: =: old. num_col;

END TempDelete;

/

REFERENCING clause

You can also use the REFERENCING clause to change the names of old and new. This clause appears after the event is triggered and before the WHEN clause. The syntax is as follows:

REFERENCING [old as old_name] [new as new_name]

In the trigger body, you can use old_name and new_name instead of old and new.

Note that the associated identifiers in the REFERENCING clause do not contain colons.

As shown in the following example:

View plaincopy to clipboardprint?

Create or replace trigger GenerateAuthorID

Before insert or update on authors

REFERENCING new AS new_author

FOR EACH ROW

BEGIN

/* Fill in the ID field of authors with the next value from

Author_sequence. Since ID is a column in authors,: new. ID

Is a valid reference .*/

SELECT author_sequence.NEXTVAL

INTO: new_author.ID

FROM dual;

END GenerateAuthorID;

/

Create or replace trigger GenerateAuthorID

Before insert or update on authors

REFERENCING new AS new_author

FOR EACH ROW

BEGIN

/* Fill in the ID field of authors with the next value from

Author_sequence. Since ID is a column in authors,: new. ID

Is a valid reference .*/

SELECT author_sequence.NEXTVAL

INTO: new_author.ID

FROM dual;

END GenerateAuthorID;

/

4. WHEN clause

The WHEN clause can only be used in row-level triggers. If the WHEN clause is provided in the definition of a row-Level Trigger, the trigger body executes only the record rows that meet the conditions defined by the WHEN. The basic form of the WHEN clause is as follows:

WHEN trigger_condition

Trigger_condition is a Boolean expression. Each time a record is processed, the value of this expression is re-determined.

You can also use: new and: old records in trigger_condition, but like the REFERENCING clause, the colon is not required when: new and: old are used in trigger_condition. The colon is only required in the trigger body.

5. Trigger predicates

You can use three Boolean functions inside a trigger to determine the operations that trigger the trigger. The three predicates are INSERTING, UPDATING, and DELETING.

The usage is shown in the following example.

View plaincopy to clipboardprint?

Create or replace trigger LogInventoryChanges

Before insert or delete or update on inventory

FOR EACH ROW

DECLARE

V_ChangeType CHAR (1 );

BEGIN

/* Use 'I' for an INSERT, 'D 'for DELETE, and 'U' for UPDATE .*/

IF INSERTING THEN

V_ChangeType: = 'I ';

ELSIF UPDATING THEN

V_ChangeType: = 'U ';

ELSE

V_ChangeType: = 'D ';

End if;

/* Record all the changes made to inventory in

Inventory_audit. Use SYSDATE to generate the timestamp, and

USER to return the userid of the current user .*/

Insert into inventory_audit

(Change_type, changed_by, timestamp,

Old_isbn, old_status, old_status_date, old_amount,

New_isbn, new_status, new_status_date, new_amount)

VALUES

(V_ChangeType, USER, SYSDATE,

: Old. isbn,: old. status,: old. status_date,: old. amount,

: New. isbn,: new. status,: new. status_date,: new. amount );

END LogInventoryChanges;

/

Create or replace trigger LogInventoryChanges

Before insert or delete or update on inventory

FOR EACH ROW

DECLARE

V_ChangeType CHAR (1 );

BEGIN

/* Use 'I' for an INSERT, 'D 'for DELETE, and 'U' for UPDATE .*/

IF INSERTING THEN

V_ChangeType: = 'I ';

ELSIF UPDATING THEN

V_ChangeType: = 'U ';

ELSE

V_ChangeType: = 'D ';

End if;

/* Record all the changes made to inventory in

Inventory_audit. Use SYSDATE to generate the timestamp, and

USER to return the userid of the current user .*/

Insert into inventory_audit

(Change_type, changed_by, timestamp,

Old_isbn, old_status, old_status_date, old_amount,

New_isbn, new_status, new_status_date, new_amount)

VALUES

(V_ChangeType, USER, SYSDATE,

: Old. isbn,: old. status,: old. status_date,: old. amount,

: New. isbn,: new. status,: new. status_date,: new. amount );

END LogInventoryChanges;

/

6. INSTEAD-OF trigger

The INSTEAD-OF triggers can only be defined on The View (relational or object), and they can be ignited in place OF the DML statements for ignition. The INSTEAD-OF Trigger must be Row-level.

7. Trigger restrictions

The trigger is subject to a PL/SQL block. All statements that can be used in PL/SQL blocks are valid in the trigger body, but are subject to the following restrictions:

The trigger should not use the transaction control statement-COMMIT, ROLLBACK, or SAVEPOINT. The trigger is ignited as part of the execution of the trigger Statement, which is in the same transaction as the trigger statement. When a trigger statement is submitted or recalled, the trigger's work is also submitted.

No process or function called by the trigger subject can use transaction control statements.

The trigger body cannot declare any LONG or long raw variables. In addition,: new and: old cannot point to LONG and long raw columns in the table that defines the trigger.

The tables that the trigger subject can access are limited.

Trigger P-Code

When the package or subroutine is stored in the data dictionary, the source code of the object is stored and the compiled p-code is stored. But this is not the case for triggers. The data dictionary only stores the source code of the trigger, rather than the p-code. Result: each time you read the trigger from the data dictionary, you must compile the trigger. This will not affect the definition and usage of the trigger, but will affect the performance of the trigger.

8. system triggers

The DML trigger and INSTEAD-OF trigger we saw earlier are both based on DML events. On the other hand, the activation of system triggers is based on two different events: DDL events or database events. DDL events include CREATE, ALTER, or DROP statements. Database events include database server startup/shutdown events, user logon/disconnection events, and server errors. The syntax for creating a system trigger is as follows:

View plaincopy to clipboardprint?

CREATE [or replace] TRIGGER [schema.] trigger_name

{BEFORE | AFTER}

{Ddl_event_list | database_event_list}

ON {DATABASE | [schema.] SCHEMA}

[When_clause]

Trigger_body;

CREATE [or replace] TRIGGER [schema.] trigger_name

{BEFORE | AFTER}

{Ddl_event_list | database_event_list}

ON {DATABASE | [schema.] SCHEMA}

[When_clause]

Trigger_body;

Ddl_event_list is one OR more DDL events separated by the OR keyword, and database_event_list is one OR more database events separated by the OR keyword.

Note: you cannot create an INSTEAD-OF system-level trigger.

By using the clause ON {DATABASE | [schema.] SCHEMA}, we can specify whether the system trigger is defined at the DATABASE or Mode Level. If an activation event occurs, the database-Level Trigger is activated. Only when an activation event occurs in a specific mode, the corresponding mode-level trigger will be activated. If you do not define the name of a specific mode when using the SCHEMA keyword, the mode with this trigger is set by default.

9. Modify the trigger status and delete the trigger

Start or disable a trigger

Alter trigger trigger_name {DISABLE | ENABLE };

Delete trigger

Drop trigger trigger_name;

You can also use the alter table command and add the enable all triggers or disable all triggers clause to ENABLE or disable all triggers on a TABLE.

Alter table table_name {ENABLE | DISABLE} all triggers;

You can use user_triggers to view the trigger information.

10. Change table and limit table

The trigger body has some restrictions on tables and columns that can be accessed. Before defining these restrictions, Let's first look at two concepts: change tables and limit tables.

Mutating table is the table being modified by the DML statement. A trigger is a table that defines the trigger. Tables that need to be updated as the results of the delete cascade referential integrity constraints are also mutating ).

A constraining table is a table that may require read operations on reference integrity restrictions.

To better understand the definition, let's look at the example below

View plaincopy to clipboardprint?

Create table registered_students (

Student_id NUMBER (5) not null,

Department CHAR (3) not null,

Course NUMBER (3) not null,

Grade CHAR (1 ),

CONSTRAINT rs_grade

CHECK (grade IN ('A', 'B', 'C', 'D', 'E ')),

CONSTRAINT rs_student_id

Foreign key (student_id) REFERENCES students (id ),

CONSTRAINT rs_department_course

Foreign key (department, course)

REFERENCES classes (department, course)

);

--...

Create table registered_students (

Student_id NUMBER (5) not null,

Department CHAR (3) not null,

Course NUMBER (3) not null,

Grade CHAR (1 ),

CONSTRAINT rs_grade

CHECK (grade IN ('A', 'B', 'C', 'D', 'E ')),

CONSTRAINT rs_student_id

Foreign key (student_id) REFERENCES students (id ),

CONSTRAINT rs_department_course

Foreign key (department, course)

REFERENCES classes (department, course)

);

--...

Registered_students has two declared integrity constraints for reference.

Both Students and classes are restricted tables of registered_students.

SQL statements in the trigger body are not allowed:

Read or modify any change table of triggering statement. These tables include triggering tables themselves.

Read or modify the primary key, unique column value (unique), or foreign key column in the triggering table. If necessary, you can modify other columns.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.