database programs cs 260 database systems. overview introduction anonymous blocks oracle’s...
TRANSCRIPT
DATABASE PROGRAMSCS 260
Database Systems
Overview
Introduction Anonymous blocks
Oracle’s PL/SQL language basics Conditions and loops Cursors and SQL commands in PL/SQL Exception handling
Stored programs Procedures Functions Packages Triggers
Introduction
A database program is used to automate data processing
It is written using a procedural language extension that is specific to the DBMS Oracle: PL/SQL
“Procedural Language/Structured Query Language” MySQL: MySQL Microsoft SQL Server: T-SQL
“Transact-SQL” IBM DB2: SQL PL
DB2 also runs PL/SQL
Introduction
Why do we need database programs? Addresses the limitations of SQL commands
SQL has no conditional statements or looping mechanisms Database programs are helpful for importing and exporting
data You can only go so far with nested queries An SQL query returns a tabular result set, stored programs
can manipulate this format Why not just put stored program logic in an
application? “Stored programs” are accessible to any application using
the db Database programs interface directly with the database
More efficient in terms of both speed and lines of code DBMS can manage security issues
Introduction
Why might we want to avoid database programs? They increase the DBMS server’s load Writing the program logic in an external
application may allow for more flexibility Database programs may be more difficult
to debug
Introduction
PL/SQL Example This stored program identifies the number
of days until Christmas
CREATE OR REPLACE FUNCTION shopping_days_xmas(current_date IN DATE) RETURN NUMBER IS shopping_days NUMBER;BEGIN shopping_days := TO_DATE('25-DEC-2015', 'DD-MON-YYYY') - current_date; RETURN shopping_days;END;
Introduction
Types of PL/SQL programs Anonymous blocks
Not persistent (not stored in the database) Cannot be called by other programs No parameters/arguments
Stored programs Stored as database objects
Procedures Functions Packages Triggers
Can be called by other programs Allow parameters/arguments
Overview
Introduction Anonymous blocks
Oracle’s PL/SQL language basics Conditions and loops Cursors and SQL commands in PL/SQL Exception handling
Stored programs Procedures Functions Packages Triggers
PL/SQL Language Basics
Basic program structure Statements may span multiple lines and
end with a semicolon Text is not case sensitive Basic anonymous block program syntax
/* block comment */DECLARE
<variable declarations>;BEGIN
<program statements>; --line commentEXCEPTION
<error handling statements>;END;
PL/SQL Language Basics
Variables Names must follow the Oracle object
naming standard Names should be descriptive Naming conventions
Use lowercase letters with words separated by underscores
Example: current_student_id
PL/SQL Language Basics
PL/SQL is a strongly-typed language All variables must be declared with a type
prior to use Declaration syntax
Declaration example
Initialization example
<variable_name> <data_type>;
current_student_id NUMBER(6);
current_student_id NUMBER(6) := 1;
PL/SQL Language Basics
Common data types SQL data types
VARCHAR2, CHAR NUMBER DATE
Non-SQL data types Integers
BINARY_INTEGER, INTEGER, INT, SMALLINT, … Real numbers
DEC, DECIMAL, DOUBLE, PRECISION, NUMBERIC, REAL, … BOOLEAN
Composite data types RECORD, TABLE, VARRAY
PL/SQL Language Basics
Reference data types %TYPE
Assumes the data type of a database field Variable declaration example
%ROWTYPE Creates a RECORD data type that holds the data
types present in the returned SQL query RECORDS are ordered collections of specific data types %ROWTYPE creates a RECORD according to the types in
a result Syntax
current_cust_name candy_customer.cust_name%TYPE;
<variable_name> <cursor_name>%ROWTYPE;
PL/SQL Language Basics
Basic OperatorsExponentiation **
Multiplication *
Division /
Addition/Subtraction +/-
Assignment :=
Comparison =
Concatenation ||
PL/SQL Language Basics
Displaying PL/SQL output using Oracle SQL Developer Enable and/or increase memory buffer
Necessary to see PL/SQL output on the console Output data to the console
SET SERVEROUTPUT ON SIZE 4000;
DBMS_OUTPUT.PUT_LINE(‘<output>’);
DBMS_OUTPUT.PUT_LINE(‘Output: ’ || <variable or function>);
PL/SQL Language Basics
Anonymous block example This program prints the current date to the
console in the format “Today is <date>”
SET SERVEROUTPUT ON SIZE 4000;
DECLARE todays_date DATE;BEGIN todays_date := SYSDATE; DBMS_OUTPUT.PUT_LINE ('Today is ' || todays_date);END;
PL/SQL Language Basics
Anonymous block example output
Overview
Introduction Anonymous blocks
Oracle’s PL/SQL language basics Conditions and loops Cursors and SQL commands in PL/SQL Exception handling
Stored programs Procedures Functions Packages Triggers
Conditions and Loops
Conditional statements Syntax
0 or more “ELSIF” statements Optional “ELSE” statement
IF <condition> THEN <statements>;ELSIF <condition> THEN <statements>;ELSE <statements>;END IF;
Conditions and Loops
Conditional statement example This program extends the functionality of the
previous program by also indicating whether Christmas is coming or has passed
DECLARE todays_date DATE;BEGIN todays_date := SYSDATE; DBMS_OUTPUT.PUT_LINE ('Today is ' || todays_date); IF todays_date > to_date('25-JUN', 'DD-MON') THEN DBMS_OUTPUT.PUT_LINE ('Christmas is coming!'); ELSE DBMS_OUTPUT.PUT_LINE ('Christmas has passed.'); END IF;END;
Conditions and Loops
EXIT WHEN loop (equivalent to Java do-while loop) Syntax
Example
LOOP <statements>;EXIT WHEN <condition>;END LOOP;
DECLARE i NUMBER;BEGIN i := 0; LOOP i := i+1; DBMS_OUTPUT.PUT_LINE ('i is ' || i); EXIT WHEN i = 10; END LOOP;END;
Conditions and Loops
WHILE loop (equivalent do Java while loop) Syntax
Example
WHILE <condition>LOOP <statements>;END LOOP;
DECLARE i NUMBER;BEGIN i := 0; WHILE i < 10 LOOP i := i+1; DBMS_OUTPUT.PUT_LINE ('i is ' || i); END LOOP;END;
Conditions and Loops
FOR loop (equivalent do Java for loop) Syntax
Example
FOR <counter> IN <start_value> .. <end_value>LOOP <statements>;END LOOP;
BEGIN FOR i IN 1 .. 10 LOOP DBMS_OUTPUT.PUT_LINE ('i is ' || i); END LOOP;END;
You cannot manually update the for loop counter within the loop
Overview
Introduction Anonymous blocks
Oracle’s PL/SQL language basics Conditions and loops Cursors and SQL commands in PL/SQL Exception handling
Stored programs Procedures Functions Packages Triggers
Cursors and SQL in PL/SQL
Using SQL within a PL/SQL ProgramSQL Command Category
Purpose Examples Can be used in PL/SQL
Data Definition Language (DDL)
Change database structure
CREATE, ALTER, GRANT, REVOKE
No
Data Manipulation Language (DML)
View or change data
SELECT, INSERT, UPDATE, DELETE
Yes
Transaction Control
Create logical transactions
COMMIT, ROLLBACK
Yes
--create table to store all dates in 2015CREATE TABLE dates_2015 ( date_value DATE );--program to insert datesSET SERVEROUTPUT ON SIZE 4000;DECLARE first_date DATE := '01-JAN-2015'; counter INT := 0;BEGIN WHILE counter < 365 LOOP INSERT INTO dates_2015 VALUES (first_date + counter); DBMS_OUTPUT.PUT_LINE(first_date + counter); counter := counter + 1; END LOOP; COMMIT;END;
Cursors and SQL in PL/SQL
Example looping program
SQL can exist in the same script as PL/SQL
DML and Transaction control can exist within PL/SQL
Cursors and SQL in PL/SQL
Using SELECT commands in PL/SQL Create a “cursor” to allow the PL/SQL
program to reference the retrieved values Cursor: “CURrent Set Of Records” Pointer to a memory location on the database
server Cursor types
Implicit Explicit
Cursors and SQL in PL/SQL
Implicit cursors Can be used for SELECT queries that return
one (and only one) record The query must return a record
Can be used to assign the column values returned by a SELECT statement into one or more variables
The variables need to be declared, but the cursor itself does not
Cursors and SQL in PL/SQL
Implicit cursors Syntax
Usage The number of variables in the INTO clause must
match the number of fields in the SELECT clause The corresponding field/variable data types must
be compatible %TYPE may be useful here
SELECT <field1>, <field2>, …INTO <variable1>, <variable2>, …FROM <table>WHERE <search_condition_that_will_return_a_single_record>;
Cursors and SQL in PL/SQL
Implicit cursor example This program places the cust_name and
cust_addr of the candy_customer with a cust_id = 1 into the program’s curr_cust_name and curr_cust_add variablesDECLARE curr_cust_name candy_customer.cust_name%TYPE; curr_cust_add candy_customer.cust_addr%TYPE;BEGIN SELECT cust_name, cust_addr INTO curr_cust_name, curr_cust_add FROM candy_customer WHERE cust_id = 1; DBMS_OUTPUT.PUT_LINE(curr_cust_name); DBMS_OUTPUT.PUT_LINE(curr_cust_add);END;
Cursors and SQL in PL/SQL
Explicit cursors Can be used for SELECT queries that return zero,
one, or multiple records Can be used to assign the column values returned
by a SELECT statement into one or more variables Both the variables and the cursor need to be
declared Explicit cursors are processed sequentially using a
loop The loop typically iterates through each record in the
result set The cursor points to the current record
Cursors and SQL in PL/SQL
Using an explicit cursor1. Declare the cursor in the DECLARE section2. Open the cursor in the program3. Fetch the cursor result into PL/SQL
program variables4. Close the cursor
Cursors and SQL in PL/SQL
Explicit cursor example This program loops through all candy_customer
cust_id and cust_name values obtained using a cursor and prints them to the console
DECLARE CURSOR customer_cursor IS SELECT cust_id, cust_name FROM candy_customer; curr_id candy_customer.cust_id%TYPE; curr_name candy_customer.cust_name%TYPE;BEGIN OPEN customer_cursor; LOOP FETCH customer_cursor INTO curr_id, curr_name; EXIT WHEN customer_cursor%NOTFOUND; DBMS_OUTPUT.PUT_LINE(curr_id || ' ' || curr_name); END LOOP; CLOSE customer_cursor;END;
Cursors and SQL in PL/SQL
Alternate version of explicit cursor example Uses a single variable of %ROWTYPE data type
instead of separate variables for each fieldDECLARE CURSOR customer_cursor IS SELECT cust_id, cust_name FROM candy_customer; customer_row customer_cursor%ROWTYPE;BEGIN OPEN customer_cursor; LOOP FETCH customer_cursor INTO customer_row; EXIT WHEN customer_cursor%NOTFOUND; DBMS_OUTPUT.PUT_LINE(customer_row.cust_id || ' ' ||
customer_row.cust_name); END LOOP; CLOSE customer_cursor;END;
Cursors and SQL in PL/SQL
Processing an explicit cursor Using a cursor FOR loop
Special syntax just for explicit cursors Automatically opens, processes, and closes the
cursor Automatically terminates after all cursor
records are processed Allows for much less code
Cursors and SQL in PL/SQL
Previous example using a cursor FOR loop
DECLARE CURSOR customer_cursor IS SELECT cust_id, cust_name FROM candy_customer; customer_row customer_cursor%ROWTYPE;BEGIN FOR customer_row IN customer_cursor LOOP --process each row DBMS_OUTPUT.PUT_LINE(customer_row.cust_id || ' ' ||
customer_row.cust_name); END LOOP;END;
Overview
Introduction Anonymous blocks
Oracle’s PL/SQL language basics Conditions and loops Cursors and SQL commands in PL/SQL Exception handling
Stored programs Procedures Functions Packages Triggers
Exception Handling
Exception handling An exception may occur due to a runtime
error or an event that violates a business rule
If the exception isn’t handled, the program will terminate and a default error message will be displayed
If the exception is handled, the program can continue executing and/or a custom error message can be displayed
Exception Handling
Program flow with and without exception handling
Program Body
System displays a default error messageand program terminates
error
Program Body
Exception handlers
error
System can display acustom error message
without with
Program optionally executes
additional statements
Exception Handling
Exception types Predefined (named)
Most common system errors have corresponding named exceptions
User-defined (named) Handle application specific errors (business
rules) Undefined (unnamed)
Used for less common system errors Built-in exception handler is associated with the
ORA error code number
Exception Handling
Syntax for handling predefined named exceptions
DECLARE <statements>;BEGIN <statements>;EXCEPTION WHEN <exception_name> THEN <statements>;END;
Exception Handling
Common PL/SQL named exceptions
Exception Handling
Handling a predefined named exception example This program retrieves and prints a cust_name to the
console, but inappropriately retrieves more than one record using an implicit cursor
The “TOO_MANY_ROWS” named exception is handled
DECLARE curr_cust_id candy_customer.cust_id%TYPE; curr_cust_name candy_customer.cust_name%TYPE;BEGIN SELECT cust_name INTO curr_cust_name FROM candy_customer; DBMS_OUTPUT.PUT_LINE(curr_cust_name);EXCEPTION WHEN TOO_MANY_ROWS THEN DBMS_OUTPUT.PUT_LINE('Change your query so it' || ' retrieves only one record');END;
Exception Handling
Syntax for creating, raising, and handling user-defined exceptions Declare exception as a variable in the DECLARE
section Raise the exception in the program (in the BEGIN
section) when appropriate using the RAISE command
DECLARE <exception_name> EXCEPTION;BEGIN RAISE <exception_name>;EXCEPTION WHEN <exception_name> THEN <statements>;END;
Exception Handling
Creating, raising, and handling a user-defined exception exampleDECLARE curr_purch_id candy_purchase.purch_id%TYPE := 1; curr_purch_date candy_purchase.purch_date%TYPE; new_delivery_date DATE := '05-SEP-07'; e_invalid_date EXCEPTION; BEGIN SELECT purch_date INTO curr_purch_date FROM candy_purchase WHERE purch_id = curr_purch_id; IF curr_purch_date <= new_delivery_date THEN UPDATE candy_purchase SET delivery_date = new_delivery_date WHERE purch_id = curr_purch_id; ELSE RAISE e_invalid_date; END IF; COMMIT; EXCEPTION WHEN e_invalid_date THEN DBMS_OUTPUT.PUT_LINE('Delivery date cannot be before purchase date, please change it'); END;
Exception Handling
Syntax for handling unnamed exceptions Unnamed exceptions can be identified by their SQL
codes Named exceptions must be handled first The SQLERRM function returns a message describing the
error Potentially useful when handling an unnamed exception
DECLARE <statements>;BEGIN <statements>;EXCEPTION -- handle named exceptions first WHEN OTHERS THEN IF SQLCODE = <sqlcode> THEN <statements>;END;
Exception Handling
Handling an unnamed exception exampleDECLARE
new_candy_product_id candy_product.prod_id%TYPE := 100;BEGIN --update an FK value using a non-existent value UPDATE candy_purchase SET prod_id = new_candy_product_id WHERE purch_id = 1;EXCEPTION -- ...named exception handlers WHEN OTHERS THEN IF SQLCODE = -2291 THEN DBMS_OUTPUT.PUT_LINE('Product ID ' || new_candy_product_id || ' does not exist.'); DBMS_OUTPUT.PUT_LINE('Message: ' || SQLERRM ); END IF;END;
SQL code list: http://psoug.org/oraerror.htm
Exception Handling
Exception scope and propagation Exception handlers only handle exceptions
thrown in their BEGIN block Nested blocks can be created so that outer
block execution isn’t impacted by inner block exceptions After an exception is raised and handled, all
uncommitted transactions are rolled back Execution resumes in the outer block
Exception Handling
Nested block syntax
DECLARE <outer block declarations>;BEGIN <outer block statements>; DECLARE
<inner block declarations>; BEGIN
<inner block statements>; EXCEPTION <inner block exception handlers>; END; <more outer block statements>;EXCEPTION <outer block exception handlers>;END;
Exception Handling
Suppose the cust_type of “W” was assumed to be removed and updated for all customers in our candy database
Write an anonymous block that does the following: Print the name and cust_type of each
customer If the cust_type is anything other than ‘P’ or
‘R’, raise a custom “invalid_cust_type” exception
If this exception is raised, the program should print the name and invalid cust_type and continue processing
Overview
Introduction Anonymous blocks
Oracle’s PL/SQL language basics Conditions and loops Cursors and SQL commands in PL/SQL Exception handling
Stored programs Procedures Functions Packages Triggers
Stored PL/SQL Programs
Can be executed by other programs and users Can accept input parameters They’re database objects
Permissions must be granted as needed Names must be unique in their schemas Follow object naming standards and conventions
Stored in a compiled form Types of stored PL/SQL programs
Procedures Functions Packages Triggers
Stored PL/SQL Programs
Parameter modes IN
Default parameter mode (used if no mode is specified) Used to pass values into the program Similar to Java’s pass-by-value argument passing scheme
OUT Used to pass values out of the program
Useful for procedures as they cannot “return” values Acts like an uninitialized variable
It should be assigned a value
IN OUT Used to both pass values into and out of the program Similar to C++’s pass-by-reference argument passing
scheme
Overview
Introduction Anonymous blocks
Oracle’s PL/SQL language basics Conditions and loops Cursors and SQL commands in PL/SQL Exception handling
Stored programs Procedures Functions Packages Triggers
Stored Procedures
Stored procedures allow parameters, can call other programs, but cannot return a value SyntaxCREATE OR REPLACE PROCEDURE <procedure_name>
(<param1> <mode> <datatype>, <param2> <mode> <datatype>, …) IS <variable declarations>;BEGIN <program statements>;EXCEPTION <exception handlers>;END;/
“AS” can be used in place of “IS”
Header
Body
Stored Procedures
Stored procedure exampleCREATE OR REPLACE PROCEDURE update_delivery_date (curr_purch_id IN candy_purchase.purch_id%TYPE, new_delivery_date IN DATE)IS -- local variable curr_purch_date candy_purchase.purch_date%TYPE; BEGIN -- implicit cursor (only one row returned) SELECT purch_date INTO curr_purch_date FROM candy_purchase WHERE purch_id = curr_purch_id; IF curr_purch_date <= new_delivery_date THEN UPDATE candy_purchase SET delivery_date = new_delivery_date WHERE purch_id = curr_purch_id; DBMS_OUTPUT.PUT_LINE('Delivery date updated'); END IF; COMMIT; END;/
Stored Procedures
Calling a stored procedure Stored procedures can be called from an
SQL script or a PL/SQL program SQL script syntax
Example
PL/SQL example (anonymous block)
EXECUTE <procedure_name>(<comma separated list of arguments);
EXECUTE update_delivery_date (1, SYSDATE);
BEGIN update_delivery_date (1, SYSDATE);END;
Overview
Introduction Anonymous blocks
Oracle’s PL/SQL language basics Conditions and loops Cursors and SQL commands in PL/SQL Exception handling
Stored programs Procedures Functions Packages Triggers
Stored Functions
Stored functions are similar to stored procedures, but they return a single value SyntaxCREATE OR REPLACE FUNCTION <function_name>
(<param1> <mode> <datatype>, <param2> <mode> <datatype>, …)RETURN <datatype> IS <variable declarations>;BEGIN <program statements>; RETURN <value>; EXCEPTION <exception handlers>; RETURN <value>;END;/
“AS” can be used in place of “IS”
Header
Body
Exception handlers should return a value
Stored Functions
Stored function example
Example call from an SQL script
CREATE OR REPLACE FUNCTION calc_diff (date1 IN DATE, date2 IN DATE)RETURN NUMBER IS days_passed NUMBER;BEGIN days_passed := date1 - date2; RETURN days_passed;END;/
SET SERVEROUTPUT ON SIZE 4000;EXEC DBMS_OUTPUT.PUT_LINE(calc_diff('25-DEC-2014', SYSDATE));
Stored Functions
Calling a stored function Stored functions can also be called from
within an SQL statement or a PL/SQL program
Syntax Can be called anywhere a value of the return
type is allowed ExamplesSELECT purch_id, calc_diff(delivery_date, purch_date)FROM candy_purchase;
SELECT purch_idFROM candy_purchaseWHERE calc_diff(delivery_date, purch_date) > 0;
Overview
Introduction Anonymous blocks
Oracle’s PL/SQL language basics Conditions and loops Cursors and SQL commands in PL/SQL Exception handling
Stored programs Procedures Functions Packages Triggers
Packages
A package is an object that groups related PL/SQL objects, such as variables, cursors, procedures, and functions
It consists of a specification and a body Specification
Declares a public interface Body
Contains a private implementation Clients can reference and call objects declared in
the specification, but not those declared in the body Similar to header and source files in C++
Packages
Benefits of packages Encapsulation of related objects Information hiding
Clients cannot see the implementation details in the body
If a procedure is declared in the body (and not the specification), it can be called only from within the package body
Better performance Package specifications and bodies are compiled
separately If changes to the body are needed, only the
package body needs to be recompiled instead of all clients that call objects in the package body
Packages
Package specification syntax
CREATE OR REPLACE PACKAGE <package_name>IS --public variables and cursors <variable_name> <datatype>; CURSOR <cursor_name> IS <SQL_statement>; … --procedures & functions PROCEDURE <procedure_name> (<parameter_list>); FUNCTION <function_name> (<parameter_list>) RETURN <data type>; …END;/
Packages
Package specification example
The public variables “max_pounds” and “curr_purch_id” can be used within the “update_pounds” and “update_delivery_date” implementations They can also be used anywhere access to the package is
allowed
CREATE OR REPLACE PACKAGE purchase_package IS --public variable declarations max_pounds NUMBER := 100; curr_purch_id candy_purchase.purch_id%TYPE;
--procedure declarations PROCEDURE update_pounds (new_pounds IN NUMBER); PROCEDURE update_delivery_date (new_delivery_date IN DATE);END;/
Packages
Example package bodyCREATE OR REPLACE PACKAGE BODY purchase_package IS PROCEDURE update_delivery_date (new_delivery_date DATE) IS curr_purch_date candy_purchase.purch_date%TYPE; BEGIN SELECT purch_date INTO curr_purch_date FROM candy_purchase WHERE purch_id = curr_purch_id; IF curr_purch_date <= new_delivery_date THEN UPDATE candy_purchase SET delivery_date = new_delivery_date WHERE purch_id = curr_purch_id; END IF; COMMIT; END; PROCEDURE update_pounds (new_pounds NUMBER) IS BEGIN IF new_pounds <= max_pounds THEN UPDATE candy_purchase SET pounds = new_pounds WHERE purch_id = curr_purch_id; END IF; COMMIT; END;END;/
Procedure 1
Procedure 2
Packages
When referencing or calling an object in a package, it is prefaced with its package name Syntax
Example (called from an SQL script)
The EXECUTE command isn’t used when referencing or calling package objects from within a PL/SQL block
For example, dbms_output.put_line(‘…’); is an example of calling a procedure inside the dbms_output package
<package_name>.<reference/call>;
EXECUTE purchase_package.curr_purch_id := 1;EXECUTE purchase_package.update_pounds(3.7);
Packages
When creating a package body, use the SHOW ERRORS command to print errors to the console
Oracle built-in packages Provide support for basic database functionality Owned by the SYS database schema Visible using the “Connections” pane in Oracle
SQL Developer Expand your schema > Other Users > SYS >
Packages
<package body>/SHOW ERRORS;
Overview
Introduction Anonymous blocks
Oracle’s PL/SQL language basics Conditions and loops Cursors and SQL commands in PL/SQL Exception handling
Stored programs Procedures Functions Packages Triggers
Triggers
Database triggers are programs that are attached to specific database tables
They may be executed in response to the following table operations: INSERT UPDATE DELETE
Triggers
Why are triggers useful? Force related operations to always happen
Update a “quantity on hand” field whenever an item is sold
Update a “current enrollment total” field whenever a student enrolls in a course section
Create an audit trail Record the username and IP address of every
user who changes a table For example, record who changed a student grade,
when they changed it, what they changed it from, and what they changed it to
Triggers
When defining a trigger, the following must be specified: Operation that causes the trigger to fire
INSERT, UPDATE, or DELETE Timing
BEFORE or AFTER the operation occurs Level
STATEMENT or ROW
Triggers
Trigger timing BEFORE
The trigger fires before the statement executes For example, for an audit trail, record the old
grade value before it is updated Though it’s still possible to accomplish this using
AFTER
AFTER The trigger fires after the statement executes For example, update the “quantity on hand”
after an item is sold
Triggers
Trigger levels ROW
The trigger fires once for each row that is affected For example, update a corresponding “quantity
on hand” value for each item that was sold STATEMENT
The trigger fires once regardless of how many rows are updated
For example, for an audit trail, you just want to record that someone updated a table, but you don’t care how many rows were updated
Triggers
Restrictions Triggers cannot have any parameters Triggers can only be created on tables that
you own Triggers cannot execute a COMMIT
command This is handled by the transaction firing the
trigger Triggers can be enabled or disabled
ALTER TRIGGER <trigger_name> <ENABLE or DISABLE>;
Triggers
Creation syntax
Choose one of “BEFORE” or “AFTER” Choose one or more of “INSERT”, “UPDATE”, and “DELETE”,
separated by “OR” “FOR EACH ROW” is optional
The trigger has statement level if omitted “WHEN (<condition>)” is optionally used only at the ROW
level Causes trigger to fire only when the row satisfied the condition
CREATE OR REPLACE TRIGGER <trigger_name> <BEFORE or AFTER> <INSERT or UPDATE or DELETE> ON <table_name> [FOR EACH ROW] [WHEN (<condition>)]BEGIN <trigger_body>;END;/
Triggers
Statement level exampleCREATE TABLE purchase_audit( date_changed DATE, user_changing VARCHAR2(30));
CREATE OR REPLACE TRIGGER purchase_audit AFTER INSERT OR UPDATE OR DELETE ON candy_purchaseBEGIN INSERT INTO purchase_audit VALUES (SYSDATE, USER);END;/SHOW ERRORS;
UPDATE candy_purchase SET pounds = 4.5 WHERE purch_id = 1 AND prod_id = 1;
SELECT * FROM purchase_audit;
USER returns the database user executing the statement
Triggers
Row level exampleCREATE TABLE purchase_audit_row(purch_id NUMBER(9), old_pounds NUMBER, new_pounds NUMBER, change_date DATE, change_user VARCHAR2(30));
CREATE OR REPLACE TRIGGER purchase_audit_row BEFORE UPDATE ON candy_purchase FOR EACH ROW BEGIN INSERT INTO purchase_audit_row VALUES( :OLD.purch_id, :OLD.pounds, :NEW.pounds, SYSDATE, USER);END;/SHOW ERRORS;
SELECT * FROM purchase_audit_row;UPDATE candy_purchase SET pounds = 15 WHERE purch_id = 5;SELECT * FROM purchase_audit_row;
:OLD.<field_name> references a field’s old value:NEW.<field_name> references a field’s new value
Triggers
Trigger design (from Oracle) Triggers should not duplicate features already
built into the database E.g. Checking constraints
If size is much more than 60 lines, place logic in a stored procedure and call from the trigger
Triggers should not be recursive For example, a trigger should not update a table if it’s
been designed to fire after updates are made to that table
Causes out of memory errors Because of their potentially frequent use, they
should be designed and implemented carefully
PL/SQL Programs in Scripts
Using PL/SQL programs in scripts PL/SQL programs in a script must be
followed by a single forward slashCREATE OR REPLACE PACKAGE show_message IS PROCEDURE hello_world;END;/CREATE OR REPLACE PACKAGE BODY show_message IS PROCEDURE hello_world IS BEGIN DBMS_OUTPUT.PUT_LINE('Hello World'); END;END;/SET SERVEROUTPUT ON SIZE 4000;BEGIN show_message.hello_world();END;/