PL/SQL – Triggers
• Triggers are stored programs, which are automatically
executed or fired when some events occur. Triggers
are, in fact, written to be executed in response to any
of the following events:
– A database manipulation (DML) statement (DELETE,
INSERT, or UPDATE).
– A database definition (DDL) statement (CREATE, ALTER, or
DROP).
– A database operation (SERVERERROR, LOGON, LOGOFF,
STARTUP, or SHUTDOWN).
• Triggers could be defined on the table, view, schema,
or database with which the event is associated.
Benefits of Triggers
• Triggers can be written for the following purposes:
• Generating some derived column values automatically
• Enforcing referential integrity
• Event logging and storing information on table access
• Auditing
• Synchronous replication of tables
• Imposing security authorizations
• Preventing invalid transactions
Creating Triggers
• The syntax for creating a trigger is:
CREATE [OR REPLACE ] TRIGGER trigger_name
{BEFORE | AFTER | INSTEAD OF }
{INSERT [OR] | UPDATE [OR] | DELETE}
[OF col_name]
ON table_name
[REFERENCING OLD AS o NEW AS n]
[FOR EACH ROW]
WHEN (condition)
DECLARE
Declaration-statements
BEGIN
Executable-statements
EXCEPTION
Exception-handling-statements
END;
Trigger Example:
• The following program creates a row level trigger for the customers table that would fire for
INSERT or UPDATE or DELETE operations performed on the CUSTOMERS table. This trigger
will display the salary difference between the old values and new values:
CREATE OR REPLACE TRIGGER display_salary_changes
BEFORE DELETE OR INSERT OR UPDATE ON customers
FOR EACH ROW
WHEN (NEW.ID > 0)
DECLARE
sal_diff number;
BEGIN
sal_diff := :NEW.salary - :OLD.salary;
dbms_output.put_line('Old salary: ' || :OLD.salary);
dbms_output.put_line('New salary: ' || :NEW.salary);
dbms_output.put_line('Salary difference: ' || sal_diff);
END;
/
• When the above code is executed at SQL prompt, it produces the following result:
Trigger created.
Triggering a Trigger
• Let us perform some DML operations on the CUSTOMERS table. Here is one INSERT
statement, which will create a new record in the table:
INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY)VALUES (7, 'Kriti', 22, 'HP',
7500.00 );
When a record is created in CUSTOMERS table, above create trigger display_salary_changes
will be fired and it will display the following result:
Old salary:
New salary: 7500
Salary difference:
• Because this is a new record so old salary is not available and above result is coming as null.
Now, let us perform one more DML operation on the CUSTOMERS table. Here is one UPDATE
statement, which will update an existing record in the table:
• UPDATE customersSET salary = salary + 500WHERE id = 2;
• When a record is updated in CUSTOMERS table, above create trigger display_salary_changes
will be fired and it will display the following result:
Old salary: 1500
New salary: 2000
Salary difference: 500
PL/SQL – Packages
• PL/SQL packages are schema objects that
groups logically related PL/SQL types,
variables and subprograms.
• A package will have two mandatory parts:
• Package specification
• Package body or definition
Package Specification
• The specification is the interface to the package. It just
DECLARES the types, variables, constants, exceptions, cursors,
and subprograms that can be referenced from outside the
package. In other words, it contains all information about the
content of the package, but excludes the code for the
subprograms.
CREATE PACKAGE cust_sal AS
PROCEDURE find_sal(c_id customers.id%type);
END cust_sal;
/
When the above code is executed at SQL prompt, it produces the
following result:
Package created.
Package Body
• The package body has the codes for various
methods declared in the package specification
and other private declarations, which are
hidden from code outside the package.
• The CREATE PACKAGE BODY Statement is used
for creating the package body. The following
code snippet shows the package body
declaration for the cust_sal package created
above.
CREATE OR REPLACE PACKAGE BODY cust_sal AS
PROCEDURE find_sal(c_id customers.id%TYPE) IS
c_sal customers.salary%TYPE;
BEGIN
SELECT salary INTO c_sal
FROM customers
WHERE id = c_id;
dbms_output.put_line('Salary: '|| c_sal);
END find_sal;
END cust_sal;
/
• When the above code is executed at SQL prompt, it produces the following
result:
– Package body created.
Using the Package Elements
• The package elements (variables, procedures or functions) are accessed
with the following syntax:
package_name.element_name;
• Consider, we already have created above package in our database schema,
the following program uses the find_sal method of the cust_sal package:
DECLARE
code customers.id%type := &cc_id;
BEGIN
cust_sal.find_sal(code);
END;
/
• When the above code is executed at SQL prompt, it prompt to enter
customer ID and when you enter an ID, it displays corresponding salary as
follows:
Enter value for cc_id: 1
Salary: 3000
• PL/SQL procedure successfully completed.
Example:
The following program provides a more complete package. We will use
the CUSTOMERS table stored in our database with the following
records:
Select * from customers;
+----+----------+-----+-----------+----------+
| ID | NAME | AGE | ADDRESS | SALARY |
+----+----------+-----+-----------+----------+
| 1 | Ramesh | 32 | Ahmedabad | 3000.00 |
| 2 | Khilan | 25 | Delhi | 3000.00 |
| 3 | kaushik | 23 | Kota | 3000.00 |
| 4 | Chaitali | 25 | Mumbai | 7500.00 |
| 5 | Hardik | 27 | Bhopal | 9500.00 |
| 6 | Komal | 22 | MP | 5500.00 |
+----+----------+-----+-----------+----------+
• THE PACKAGE SPECIFICATION:
CREATE OR REPLACE PACKAGE c_package AS
-- Adds a customer
PROCEDURE addCustomer(c_id customers.id%type,
c_name customers.name%type,
c_age customers.age%type,
c_addr customers.address%type,
c_sal customers.salary%type);
-- Removes a customer
PROCEDURE delCustomer(c_id customers.id%TYPE);
--Lists all customers
PROCEDURE listCustomer;
END c_package;
/
When the above code is executed at SQL prompt, it creates the above
package and displays the following result:
Package created.
CREATING THE PACKAGE BODY:
CREATE OR REPLACE PACKAGE BODY c_package AS
PROCEDURE addCustomer(c_id customers.id%type, c_name customers.name%type, c_age
customers.age%type, c_addr customers.address%type, c_sal customers.salary%type)
IS
BEGIN
INSERT INTO customers (id,name,age,address,salary) VALUES(c_id, c_name, c_age, c_addr, c_sal);
END addCustomer;
PROCEDURE delCustomer(c_id customers.id%type) IS
BEGIN
DELETE FROM customers WHERE id = c_id;
END delCustomer;
………………
PROCEDURE listCustomer IS
CURSOR c_customers is
SELECT name FROM customers;
TYPE c_list is TABLE OF customers.name%type;
name_list c_list := c_list();
counter integer :=0;
BEGIN
FOR n IN c_customers LOOP
counter := counter +1;
name_list.extend;
name_list(counter) := n.name;
dbms_output.put_line('Customer(' ||counter|| ')'||name_list(counter));
END LOOP;
END listCustomer;
END c_package;
/
Above example makes use of nested table which we will discuss in the next chapter. When the
above code is executed at SQL prompt, it produces the following result:
Package body created.
USING THE PACKAGE:
The following program uses the methods declared and
defined in the package c_package.
DECLARE
code customers.id%type:= 8;
BEGIN
c_package.addcustomer(7, 'Rajnish', 25, 'Chennai', 3500);
c_package.addcustomer(8, 'Subham', 32, 'Delhi', 7500);
c_package.listcustomer;
c_package.delcustomer(code);
c_package.listcustomer;
END;
/

PL/SQL TRIGGERS

  • 1.
    PL/SQL – Triggers •Triggers are stored programs, which are automatically executed or fired when some events occur. Triggers are, in fact, written to be executed in response to any of the following events: – A database manipulation (DML) statement (DELETE, INSERT, or UPDATE). – A database definition (DDL) statement (CREATE, ALTER, or DROP). – A database operation (SERVERERROR, LOGON, LOGOFF, STARTUP, or SHUTDOWN). • Triggers could be defined on the table, view, schema, or database with which the event is associated.
  • 2.
    Benefits of Triggers •Triggers can be written for the following purposes: • Generating some derived column values automatically • Enforcing referential integrity • Event logging and storing information on table access • Auditing • Synchronous replication of tables • Imposing security authorizations • Preventing invalid transactions
  • 3.
    Creating Triggers • Thesyntax for creating a trigger is: CREATE [OR REPLACE ] TRIGGER trigger_name {BEFORE | AFTER | INSTEAD OF } {INSERT [OR] | UPDATE [OR] | DELETE} [OF col_name] ON table_name [REFERENCING OLD AS o NEW AS n] [FOR EACH ROW] WHEN (condition) DECLARE Declaration-statements BEGIN Executable-statements EXCEPTION Exception-handling-statements END;
  • 4.
    Trigger Example: • Thefollowing program creates a row level trigger for the customers table that would fire for INSERT or UPDATE or DELETE operations performed on the CUSTOMERS table. This trigger will display the salary difference between the old values and new values: CREATE OR REPLACE TRIGGER display_salary_changes BEFORE DELETE OR INSERT OR UPDATE ON customers FOR EACH ROW WHEN (NEW.ID > 0) DECLARE sal_diff number; BEGIN sal_diff := :NEW.salary - :OLD.salary; dbms_output.put_line('Old salary: ' || :OLD.salary); dbms_output.put_line('New salary: ' || :NEW.salary); dbms_output.put_line('Salary difference: ' || sal_diff); END; / • When the above code is executed at SQL prompt, it produces the following result: Trigger created.
  • 5.
    Triggering a Trigger •Let us perform some DML operations on the CUSTOMERS table. Here is one INSERT statement, which will create a new record in the table: INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY)VALUES (7, 'Kriti', 22, 'HP', 7500.00 ); When a record is created in CUSTOMERS table, above create trigger display_salary_changes will be fired and it will display the following result: Old salary: New salary: 7500 Salary difference: • Because this is a new record so old salary is not available and above result is coming as null. Now, let us perform one more DML operation on the CUSTOMERS table. Here is one UPDATE statement, which will update an existing record in the table: • UPDATE customersSET salary = salary + 500WHERE id = 2; • When a record is updated in CUSTOMERS table, above create trigger display_salary_changes will be fired and it will display the following result: Old salary: 1500 New salary: 2000 Salary difference: 500
  • 6.
    PL/SQL – Packages •PL/SQL packages are schema objects that groups logically related PL/SQL types, variables and subprograms. • A package will have two mandatory parts: • Package specification • Package body or definition
  • 7.
    Package Specification • Thespecification is the interface to the package. It just DECLARES the types, variables, constants, exceptions, cursors, and subprograms that can be referenced from outside the package. In other words, it contains all information about the content of the package, but excludes the code for the subprograms. CREATE PACKAGE cust_sal AS PROCEDURE find_sal(c_id customers.id%type); END cust_sal; / When the above code is executed at SQL prompt, it produces the following result: Package created.
  • 8.
    Package Body • Thepackage body has the codes for various methods declared in the package specification and other private declarations, which are hidden from code outside the package. • The CREATE PACKAGE BODY Statement is used for creating the package body. The following code snippet shows the package body declaration for the cust_sal package created above.
  • 9.
    CREATE OR REPLACEPACKAGE BODY cust_sal AS PROCEDURE find_sal(c_id customers.id%TYPE) IS c_sal customers.salary%TYPE; BEGIN SELECT salary INTO c_sal FROM customers WHERE id = c_id; dbms_output.put_line('Salary: '|| c_sal); END find_sal; END cust_sal; / • When the above code is executed at SQL prompt, it produces the following result: – Package body created.
  • 10.
    Using the PackageElements • The package elements (variables, procedures or functions) are accessed with the following syntax: package_name.element_name; • Consider, we already have created above package in our database schema, the following program uses the find_sal method of the cust_sal package: DECLARE code customers.id%type := &cc_id; BEGIN cust_sal.find_sal(code); END; / • When the above code is executed at SQL prompt, it prompt to enter customer ID and when you enter an ID, it displays corresponding salary as follows: Enter value for cc_id: 1 Salary: 3000 • PL/SQL procedure successfully completed.
  • 11.
    Example: The following programprovides a more complete package. We will use the CUSTOMERS table stored in our database with the following records: Select * from customers; +----+----------+-----+-----------+----------+ | ID | NAME | AGE | ADDRESS | SALARY | +----+----------+-----+-----------+----------+ | 1 | Ramesh | 32 | Ahmedabad | 3000.00 | | 2 | Khilan | 25 | Delhi | 3000.00 | | 3 | kaushik | 23 | Kota | 3000.00 | | 4 | Chaitali | 25 | Mumbai | 7500.00 | | 5 | Hardik | 27 | Bhopal | 9500.00 | | 6 | Komal | 22 | MP | 5500.00 | +----+----------+-----+-----------+----------+
  • 12.
    • THE PACKAGESPECIFICATION: CREATE OR REPLACE PACKAGE c_package AS -- Adds a customer PROCEDURE addCustomer(c_id customers.id%type, c_name customers.name%type, c_age customers.age%type, c_addr customers.address%type, c_sal customers.salary%type); -- Removes a customer PROCEDURE delCustomer(c_id customers.id%TYPE); --Lists all customers PROCEDURE listCustomer; END c_package; / When the above code is executed at SQL prompt, it creates the above package and displays the following result: Package created.
  • 13.
    CREATING THE PACKAGEBODY: CREATE OR REPLACE PACKAGE BODY c_package AS PROCEDURE addCustomer(c_id customers.id%type, c_name customers.name%type, c_age customers.age%type, c_addr customers.address%type, c_sal customers.salary%type) IS BEGIN INSERT INTO customers (id,name,age,address,salary) VALUES(c_id, c_name, c_age, c_addr, c_sal); END addCustomer; PROCEDURE delCustomer(c_id customers.id%type) IS BEGIN DELETE FROM customers WHERE id = c_id; END delCustomer; ………………
  • 14.
    PROCEDURE listCustomer IS CURSORc_customers is SELECT name FROM customers; TYPE c_list is TABLE OF customers.name%type; name_list c_list := c_list(); counter integer :=0; BEGIN FOR n IN c_customers LOOP counter := counter +1; name_list.extend; name_list(counter) := n.name; dbms_output.put_line('Customer(' ||counter|| ')'||name_list(counter)); END LOOP; END listCustomer; END c_package; / Above example makes use of nested table which we will discuss in the next chapter. When the above code is executed at SQL prompt, it produces the following result: Package body created.
  • 15.
    USING THE PACKAGE: Thefollowing program uses the methods declared and defined in the package c_package. DECLARE code customers.id%type:= 8; BEGIN c_package.addcustomer(7, 'Rajnish', 25, 'Chennai', 3500); c_package.addcustomer(8, 'Subham', 32, 'Delhi', 7500); c_package.listcustomer; c_package.delcustomer(code); c_package.listcustomer; END; /