Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Microsoft Access wikipedia , lookup
Oracle Database wikipedia , lookup
Entity–attribute–value model wikipedia , lookup
Extensible Storage Engine wikipedia , lookup
Concurrency control wikipedia , lookup
Open Database Connectivity wikipedia , lookup
Microsoft SQL Server wikipedia , lookup
Microsoft Jet Database Engine wikipedia , lookup
Ingres (database) wikipedia , lookup
Clusterpoint wikipedia , lookup
Database model wikipedia , lookup
Database Laboratory Creating Database Triggers (Implementation in DBMS Oracle) Author: Aleksandra Werner, PhD Database Laboratory, ...Triggers -1- 1. Introduction. Triggers are procedures written in PL/SQL (or C and Java) that are stored in the database and execute ("fire") implicitly whenever a particular event takes place. In Oracle, triggers fire whenever one of the following operations occurs: DML statements (INSERT, UPDATE, or DELETE) on a particular schema object (table or, in some cases, a view), DDL statements issued within a schema or database, user logon or logoff events, server errors, database startup, or instance shutdown. Triggers are similar to stored procedures. However, procedures and triggers differ in the way that they are invoked. A procedure is explicitly executed by a user, application, or trigger. Triggers (one or more) are implicitly fired (executed) when a triggering event occurs, no matter which user is connected or which application is being used. More differences are shown in table 1. A database application with some SQL statements that implicitly fire several triggers is stored in the database and the database stores triggers separately from their associated tables. 2. Triggers usability. Triggers can supplement the standard capabilities of Oracle to provide a highly customized database management system. For example, a trigger can restrict DML operations against a table to those issued during regular business hours. A trigger could also restrict DML operations to occur only at certain times during weekdays. Other uses for triggers are to automatically generate derived column values prevent invalid transactions enforce complex security authorizations enforce referential integrity across nodes in a distributed database enforce complex business rules provide transparent event logging provide sophisticated auditing maintain synchronous table replicates gather statistics on table access modify table data when DML statements are issued against views Gliwice, 2002 -2- Database Laboratory, ...Triggers publish information about database events, user events, and SQL statements to subscribing applications Although triggers are useful for customizing a database, they should be used only when necessary. Excessive use of triggers can result in complex interdependencies, which may be difficult to maintain in a large application. For example, when a trigger fires, a SQL statement within its trigger action potentially can fire other triggers, resulting in cascading triggers. Triggers can be used to publish information about database events to subscribers. Applications can subscribe to database events just as they subscribe to messages from other applications. These database events can include: system events o database startup and shutdown, o server error message events, user events o user logon and logoff, o DDL statements (CREATE, ALTER, and DROP), o DML statements (INSERT, DELETE, and UPDATE). 2.1. System Events System events that can fire triggers are related to instance startup and shutdown and error messages. Triggers created on startup and shutdown events have to be associated with the database; triggers created on error events can be associated with the database or with a schema. STARTUP triggers fire when the database is opened by an instance. Their attributes include the system event, instance number, and database name. SHUTDOWN triggers fire just before the server starts shutting down an instance. Triggers can be used to make subscribing applications shut down completely when the database shuts down. (For abnormal instance shutdown these triggers may not be fired). The attributes of SHUTDOWN triggers include the system event, instance number and database name. SERVERERROR triggers fire when a specified error occurs, or when any error occurs if no error number is specified. Their attributes include the system event and error number. Gliwice, 2002 Database Laboratory, ...Triggers -3- 2.2. User Events User events that can fire triggers are related to user logon and logoff, DDL statements and DML statements. 2.2.1 Triggers on LOGON and LOGOFF Events LOGON and LOGOFF triggers can be associated with the database or with a schema. Their attributes include the system event and username, and they can specify simple conditions on USERID and USERNAME. LOGON triggers fire after a successful logon of a user. LOGOFF triggers fire at the start of a user logoff. 2.2.2 Triggers on DDL Statements DDL triggers can be associated with the database or with a schema. Their attributes include the system event, the type of schema object and its name. They can specify simple conditions on the type and name of the schema object, as well as functions (like USERID and USERNAME). BEFORE CREATE and AFTER CREATE triggers fire when a schema object is created in the database or schema. BEFORE ALTER and AFTER ALTER triggers fire when a schema object is altered in the database or schema. BEFORE DROP and AFTER DROP triggers fire when a schema object is dropped from the database or schema. 2.2.3 Triggers on DML Statements DML triggers for event publication are associated with a table. They can be either BEFORE or AFTER triggers that fire for each row on which the specified DML operation occurs. INSTEAD OF triggers can’t be used on views to publish events related to DML statements; instead, they can publish events using BEFORE or AFTER triggers for the DML operations on a view's underlying tables that are caused by INSTEAD OF triggers. The attributes of DML triggers for event publication include the system event and the columns defined by the user in the SELECT list. They can specify simple conditions on the type and name of the schema object, as well as functions (such as UID, USER, USERENV, and SYSDATE), pseudocolumns, and columns. The columns may be prefixed by :OLD and :NEW for old and new values. Gliwice, 2002 -4- Database Laboratory, ...Triggers BEFORE INSERT and AFTER INSERT triggers fire for each row inserted into the table. BEFORE UPDATE and AFTER UPDATE triggers fire for each row updated in the table. BEFORE DELETE and AFTER DELETE triggers fire for each row deleted from the table. 3. Parts of a Trigger A trigger has three basic parts: a triggering event or statement a trigger restriction a trigger action 3.1. Triggering Event or Statement A triggering event or statement is the SQL statement, database event or user event, that causes a trigger to be fired. A triggering event can be one or more of the following: an INSERT, UPDATE, or DELETE statement on a specific table (or view, in some cases), a CREATE, ALTER, or DROP statement on any schema object, a database startup or instance shutdown, a specific error message or any error message, a user logon or logoff. 3.2. Trigger Restriction A trigger restriction specifies a Boolean (logical) expression that must be TRUE for the trigger to fire. The trigger action is not executed if the trigger restriction evaluates to FALSE or UNKNOWN. For example, the trigger restriction might be: new.extra_money < new.salary 3.2.1 WHEN Clause Optionally, a trigger restriction can be included in the definition only of a row trigger, by specifying a Boolean SQL expression in a WHEN clause. The WHEN clause can’t be Gliwice, 2002 Database Laboratory, ...Triggers -5- specified for INSTEAD OF triggers. If included, then the expression in the WHEN clause is evaluated for each row that the trigger affects. If the expression evaluates to TRUE for a row, then the trigger body is fired on behalf of that row. However, if the expression evaluates to FALSE or NOT TRUE for a row (unknown, as with nulls), then the trigger body is not fired for that row. The evaluation of the WHEN clause does not have an effect on the execution of the triggering SQL statement (in other words, the triggering statement is not rolled back if the expression in a WHEN clause evaluates to FALSE). For example, the trigger body wouldn’t run if the new value of Empno were zero, NULL, or negative. WHEN (new.empno = 0) In more realistic examples, you might test if one column value is less than another. The expression in a WHEN clause of a row trigger can include correlation names. The expression in a WHEN clause must be a SQL expression and it cannot include a subquery. A PL/SQL expression (including user-defined functions) can’t be used in the WHEN clause. 3.3. Trigger Action A trigger action is the procedure, that contains the SQL statements and code to be executed when a triggering statement is issued and the trigger restriction evaluates to TRUE. A trigger action can contain SQL and PL/SQL or Java statements, define PL/SQL language constructs (variables, constants, cursors, exceptions, and so on) or Java language constructs, and call stored procedures. Additionally, for row triggers, the statements in a trigger action have access to column values (new and old) of the current row being processed by the trigger. Correlation names provide access to the old and new values for each column. For example, trigger action might be: BEGIN UPDATE audit_table SET upd = upd + 1 WHERE user_name = ‘laboratory’ AND column_name IS NULL; END; 4. Types of Triggers This section describes the different types of triggers: Row Triggers and Statement Triggers BEFORE and AFTER Triggers INSTEAD-OF Triggers Triggers on System Events Database Triggers and User Events Application Trigger 4.1. Row Triggers and Statement Triggers Gliwice, 2002 Database Laboratory, ...Triggers -6- While defining a trigger, the number of times the trigger action is to be executed can be specified: once for every row affected by the triggering statement (such as might be fired by an UPDATE statement that updates many rows), or: once for the triggering statement, no matter how many rows it affects. 4.2. Row Triggers A row trigger is fired each time the table is affected by the triggering statement. For example, if an UPDATE statement updates multiple rows of a table, a row trigger is fired once for each row affected by the UPDATE statement. If a triggering statement affects no rows, a row trigger is not executed at all. Row triggers are useful if the code in the trigger action depends on data provided by the triggering statement or rows that are affected. 4.3. Statement Triggers A statement trigger is fired once on behalf of the triggering statement, regardless of the number of rows in the table that the triggering statement affects (even if no rows are affected). For example, if a DELETE statement deletes several rows from a table, a statementlevel DELETE trigger is fired only once, regardless of how many rows are deleted from the table. Statement triggers are useful if the code in the trigger action does not depend on the data provided by the triggering statement or the rows affected. For example, if a trigger makes a complex security check on the current time or user, or if a trigger generates a single audit record based on the type of triggering statement, a statement trigger is used. 4.4. BEFORE and AFTER Triggers When defining a trigger, the trigger timing can be specified (it means whether the trigger action is to be executed before or after the triggering statement). BEFORE and AFTER apply to both: statement and row triggers. BEFORE and AFTER triggers fired by DML statements can be defined only on tables, not on views. However, triggers on the base table(s) of a view are fired if an INSERT, UPDATE, or DELETE statement is issued against the view. BEFORE and AFTER triggers fired by DDL statements can be defined only on the database or a schema, not on particular tables. 4.5. BEFORE Triggers BEFORE triggers execute the trigger action before the triggering statement is executed. This type of trigger is commonly used in the following situations: Gliwice, 2002 Database Laboratory, ...Triggers -7- When the trigger action should determine whether the triggering statement should be allowed to complete. Using a BEFORE trigger for this purpose, you can eliminate unnecessary processing of the triggering statement and its eventual rollback in cases where an exception is raised in the trigger action. To derive specific column values before completing a triggering INSERT or UPDATE statement. 4.6. AFTER Triggers AFTER triggers execute the trigger action after the triggering statement is executed. AFTER triggers are used when you want the triggering statement to complete before executing the trigger action. 4.7. Trigger Type Combinations Using the options listed above, four types of row and statement triggers can be created: BEFORE statement trigger Before executing the triggering statement, the trigger action is executed. BEFORE row trigger Before modifying each row affected by the triggering statement and before checking appropriate integrity constraints, the trigger action is executed provided that the trigger restriction was not violated. AFTER row trigger After modifying each row affected by the triggering statement and possibly applying appropriate integrity constraints, the trigger action is executed for the current row. Unlike BEFORE row triggers, AFTER row triggers lock rows. AFTER statement trigger After executing the triggering statement and applying any deferred integrity constraints, the trigger action is executed. Multiple triggers of the same type for the same statement for any given table can be defined. For example two BEFORE statement triggers for UPDATE statements on the EMP table could be defined. Multiple triggers of the same type permit modular installation of applications that have triggers on the same tables. Also, Oracle snapshot logs use AFTER row triggers, so you can design your own AFTER row trigger in addition to the Oracle-defined AFTER row trigger. INSTEAD-OF Triggers INSTEAD-OF triggers provide a transparent way of modifying views that cannot be modified directly through SQL DML statements (INSERT, UPDATE, and Gliwice, 2002 Database Laboratory, ...Triggers -8- DELETE). These triggers are called INSTEAD-OF triggers because, unlike other types of triggers, Oracle fires the trigger instead of executing the triggering statement. Normal INSERT, UPDATE, and DELETE statements against the view can be written and the INSTEAD-OF trigger is fired to update the underlying tables appropriately. INSTEAD-OF triggers are activated for each row of the view that gets modified. 5. Creating Triggers 5.1. Syntax for creating Statement Triggers CREATE [OR REPLACE] TRIGGER trigger_name timing event1 [OR event2 OR event3] ON table_name BEGIN | DECLARE PL/SQL block END; You can combine several triggering events into one by takinkg advantage of the special conditional predicates INSERTING, UPDATING, DELETING within the trigger body. 5.2. Syntax for creating Row Triggers CREATE [OR REPLACE] TRIGGER trigger_name timing event1 [OR event2 OR event3] ON table_name [REFERENCING OLD AS old | NEW AS new] FOR EACH ROW [WHEN condition] BEGIN | DECLARE PL/SQL block END; 5.3. Removing Triggers To remove a trigger from the database, use syntax: DROP TRIGGER trigger_name; Gliwice, 2002 Database Laboratory, ...Triggers -9- 5.4. Managing Triggers Syntax for disabling or re-enabling a database trigger: ALTER TRIGGER trigger_name DISABLE | ENABLE; Syntax for disabling or re-enabling all triggers for a table: ALTER TABLE table_name DISABLE | ENABLE ALL TRIGGERS; Syntax for recompiling a trigger for a table: ALTER TRIGGER trigger_name COMPILE; 6. Listing Information About Triggers The following data dictionary views reveal information about triggers: USER_TRIGGERS ALL_TRIGGERS DBA_TRIGGERS To list information from a view, use syntax: SELECT * FROM data_dictionary_view; The new column, BASE_OBJECT_TYPE, specifies whether the trigger is based on DATABASE, SCHEMA, table, or view. The old column, TABLE_NAME, is null if the base object is not table or view. The column ACTION_TYPE specifies whether the trigger is a call type trigger or a PL/SQL trigger. The column TRIGGER_TYPE includes two additional values: BEFORE EVENT and AFTER EVENT, applicable only to system events. The column TRIGGERING_EVENT includes all system and DML events. The following data dictionary views reveal information about triggers compilation errors: USER_ERRORS ALL_ ERRORS DBA_ ERRORS Gliwice, 2002 Database Laboratory, ...Triggers 10 - Table 1. Different types of Triggers - summary Types of Triggers INSTEAD OF BEFORE AFTER STATEMENT ROW The code in the trigger The code in the trigger The code in the trigger The code in the trigger The code in the trigger body will execute body will execute body will execute after body executes once for body executes once for instead of the triggering before the triggering the triggering DML each row affected by the triggering event. statement. DML event. event. triggering event. Is used for views, that are not otherwise modifiable. Gliwice, 2002 Is fired once, even if no rows are affected at all. If the triggering event affects no row(-s), a row trigger is not executed at all. Database Laboratory, ...Triggers - 11 - Table 2. Differences between Triggers and Procedures Triggers Procedure Triggers are procedures, that are stored in the database and Procedures are blocks of PL/SQL, which are explicitly invoked implicitly (automatically) run (fired), when sth happens. by a user, application, or trigger. It doesn’t matter which user is connected or which application is Can take parameters whose value is passed to, populated by the being used. calling environment. Triggers might be database triggers or an application triggers. Procedures might be client-side or server-side. Can be defined on tables and on views. Can be defined on tables and on views. Can be written in PL/SQL or Java and stored in the database, or Can be written is PL/SQL. they can be written as C callouts. COMMIT, SAVEPOINT, ROLLBACK not allowed within the COMMIT, SAVEPOINT, ROLLBACK allowed within the trigger body. procedure body. The source code is compiled into p-code. The source code is compiled into p-code. Gliwice, 2002 Database Laboratory, ...Triggers 12 - Table 3. Syntax for Creating a Row Trigger Components of CREATE TRIGGER statement Trigger_name Meaning The name of the trigger. Trigger names must be unique with respect to other triggers in the same schema. Trigger names do not need to be unique with respect to other schema objects, such as tables, views, and procedures. For example, a table and a trigger can have the same name. Timing Indicates the time when the trigger fires in relation to the triggering event: BEFORE AFTER INSTEAD OF Event Identifies the DML operation, that causes the trigger to fire: INSERT UPDATE [OF column] DELETE Table_name Indicates the table associated with trigger. Referencing Specifies correlation names for the old and new values of the current row (the default are: OLD and: NEW). FOR EACH ROW Designates the trigger to be a row trigger. WHEN Specifies the trigger restriction. This conditional predicate is evaluated for each row to determine whether or not the trigger body is executed. PL/SQL block Is the trigger body, that defines the action performed by trigger, beginning with either DECLARE or BEGIN, ending with END. Gliwice, 2002 Database Laboratory, ...Triggers - 13 - 7. PL/SQL 7.1. Anonymous PL/SQL block The trigger body is defined with an anonymous PL/SQL block: [DECLARE] BEGIN [EXCEPTIONS] END; 7.2. PL/SQL control structures Any PL/SQL procedure can be written using the basic control structures shown in fig. 1. Iteration Selection T Sequence F F T Fig. 1. Control structures 7.2.1 Conditional control The selection structure tests a condition, then executes one sequence of statements instead of another, depending on whether the condition is true or false. A condition is any variable or expression that returns a Boolean value (TRUE, FALSE, NULL). There are three forms of IF statements: IF – THEN IF – THEN – ELSE IF – THEN – ELSIF IF condition THEN sequence_of_statements; END IF; IF condition THEN sequence_of_statements1; ELSE sequence_of_statements2; END IF; IF condition1 THEN Gliwice, 2002 Database Laboratory, ...Triggers 14 sequence_of_statements1; ELSIF condition2 THEN sequence_of_statements2; ELSE sequence_of_statements3; END IF; 7.2.2 Iterative control There are three forms of LOOP statements: LOOP (The EXIT statement forces a loop to complete unconditionally; the EXIT-WHEN statement allows a loop to complete conditionally), WHILE-LOOP, FOR-LOOP. WHILE condition LOOP sequence_of_statements; END LOOP; LOOP sequence_of_statements; END LOOP; FOR counter IN [REVERSE] lower_bound..higher_bound LOOP sequence_of_statements; END LOOP; 7.2.3 Sequential control: GOTO and NULL statements The GOTO statement branches to a label unconditionally. The label must be unique within its scope and must precede an executable statement or PL/SQL block. When executed, the GOTO statement transfers control to the labeled statement or block. The NULL statement can make the meaning and action of conditional statements clear and so improve readability. 8. Examples Create a trigger to restrict all data manipulation events on the EMP table to certain business hours, Monday through Friday. Solution: as many triggers of the preceding different types as are need, might be created for each type of DML statement (INSERT, UPDATE, or DELETE). Gliwice, 2002 Database Laboratory, ...Triggers - 15 - CREATE OR REPLACE TRIGGER secure_emp BEFORE INSERT OR UPDATE OR DELETE ON emp BEGIN IF (TO_CHAR (sysdate, ‘DY’) IN (‘SAT’,’SUN’)) OR (TO_CHAR (sysdate, ‘HH24’) NOT BETWEEN ‘08’ AND ‘18’) THEN IF DELETING RAISE_APPLICATION_ERROR is a server-side built-in procedure that prints a message to the user and causes the PL/SQL block to fail. THEN RAISE_APPLICATION_ERROR (-20502, ‘You may delete only during normal hours’); ELSEIF INSERTING THEN RAISE_APPLICATION_ERROR (-20500, ‘You may insert only during normal hours’); ELSE THEN RAISE_APPLICATION_ERROR (-20504, ‘You may update only during normal hours’); END IF; END IF; END; Attention: when a database fails, triggering statement is automatically rolled back by the Oracle Server. Enforce referential integrity with a trigger. When the value of deptno changes in the DEPT parent table, cascade the update to the corresponding rows in the EMP child table. Let DEPT be a relational table containing a list of departments, CREATE TABLE dept ( deptno NUMBER, deptname VARCHAR2(20), manager_num NUMBER ); Let EMP be a relational table containing the list of employees and the departments in which they work. CREATE TABLE emp ( empno NUMBER PRIMARY KEY, empname VARCHAR2(20), deptno NUMBER, startdate DATE Gliwice, 2002 Database Laboratory, ...Triggers 16 ); Gliwice, 2002 Database Laboratory, ...Triggers - 17 - Solution: CREATE OR REPLACE TRIGGER cascade_updates AFTER UPDATE OF deptno ON emp FOR EACH ROW BEGIN UPDATE emp SET emp.deptno = :new.deptno WHERE emp.deptno = :old.deptno; END; Create an INSTEAD OF trigger for inserting rows into the MANAGER_INFO view, which was creating in such way: CREATE VIEW manager_info AS SELECT e.name, e.empname, d.dept_type, d.deptno FROM emp e, dept d WHERE e.empno = d.mgr_no; Solution: CREATE OR REPLACE TRIGGER manager_info_insert INSTEAD OF INSERT ON manager_info FOR EACH ROW BEGIN IF NOT EXISTS SELECT * FROM emp WHERE emp.empno = :new.empno THEN INSERT INTO emp VALUES (:new.empno, :new.name); ELSE UPDATE emp SET emp.name = :new.name WHERE emp.empno = :new.empno; END IF; IF NOT EXISTS SELECT * FROM dept WHERE dept.deptno = :new.deptno THEN INSERT INTO dept VALUES (:new. deptno, :new.dept_type); ELSE UPDATE dept SET dept.dept_type = :new.dept_type WHERE emp. deptno = :new. deptno; END IF; END; Gliwice, 2002