Presentation is loading. Please wait.

Presentation is loading. Please wait.

CS4222 Principles of Database System

Similar presentations


Presentation on theme: "CS4222 Principles of Database System"— Presentation transcript:

1 CS4222 Principles of Database System
9/21/2018 CS4222 Principles of Database System 14. PL/PgSQL 2 Huiping Guo Department of Computer Science California State University, Los Angeles

2 Returning Variables RETURN expression;
9/21/2018 Returning Variables RETURN expression; RETURN NEXT expression/ RETURN QUERY query; RETURN; RETURN statement is required even for functions that return void RETURN NEXT/ RETURN QUERY They do not actually return from the function — they simply append zero or more rows to the function's result set. Execution then continues with the next statement in the PL/pgSQL function. As successive RETURN NEXT or RETURN QUERY commands are executed, the result set is built up. A final RETURN, which should have no argument, causes control to exit the function 14. PL/pgSQL CS4222_Su17

3 Example Select * from getAllFoo();
9/21/2018 Example CREATE TABLE foo (fooid INT, foosubid INT, fooname TEXT); INSERT INTO foo VALUES (1, 2, 'three'); INSERT INTO foo VALUES (4, 5, 'six'); CREATE OR REPLACE FUNCTION getAllFoo() RETURNS SETOF foo AS ' DECLARE r foo%rowtype; BEGIN FOR r IN SELECT * FROM foo WHERE fooid > 0 LOOP RETURN NEXT r; -- return current row of SELECT END LOOP; RETURN; END ; ' LANGUAGE 'plpgsql' ; Select * from getAllFoo(); 14. PL/pgSQL CS4222_Su17

4 Handling Errors and Exceptions
RAISE statement Syntax RAISE level ''message string'' [, identifier [...] ]; Possible level values: DEBUG, NOTICE, EXCEPTION 14. PL/pgSQL CS4222_Su17

5 Severity Levels Level Message written to server’s log
Message prompted to the screen Function runs to completion Current transaction aborted DEBUG YES NO NOTICE EXCEPTION 14. PL/pgSQL CS4222_Su17

6 Typical Uses of Severity Levels
DEBUG When debugging software in working environment NOTICE To inform user about some interesting event which does not adversely affect the execution EXCEPTION To abort transaction due to some foreseen event and inform user about that 14. PL/pgSQL CS4222_Su17

7 Raise statement example
CREATE FUNCTION raise_test() RETURNS integer AS ' DECLARE an_integer INTEGER := 1; BEGIN -- Raise a debug level message RAISE DEBUG ''The raise_test function began.''; an_integer := an_integer + 1; RAISE NOTICE ''Variable an_integer was changed.''; RAISE NOTICE ''Variable an_integer value is now %.'',an_integer; -- Raise an exception. RAISE EXCEPTION ''Variable % changed. Transaction aborted.'',an_integer; RETURN 1; END; ' LANGUAGE 'plpgsql'; 14. PL/pgSQL CS4222_Su17

8 Results of the raise_test( ) function
SELECT raise_test(); NOTICE: Variable an_integer was changed. NOTICE: Variable an_integer's value is now 2. ERROR: Variable 2 changed. Aborting transaction. 14. PL/pgSQL CS4222_Su17

9 Cursors Rather than executing a whole query at once, it is possible to set up a cursor that encapsulates the query, and then read the query result a few rows at a time To create a cursor variable One way to create a cursor variable is just to declare it as a variable of type refcursor Another way is to use the cursor declaration syntax name CURSOR [ ( arguments ) ] FOR query ; 14. PL/pgSQL CS4222_Su17

10 Examples DECLARE curs1 refcursor;
curs2 CURSOR FOR SELECT * FROM table1; curs3 CURSOR (k integer) FOR SELECT * FROM table1 WHERE key=k; Unbound cursor: curs1 Bound cursors: curs2, curs3 14. PL/pgSQL CS4222_Su17

11 Opening and closing cursors
Before a cursor can be used to retrieve rows, it must be opened OPEN curs1 FOR SELECT * FROM table2; OPEN curs2; OPEN curs3(47); Close curs1; 14. PL/pgSQL CS4222_Su17

12 Fetching From a Cursor FETCH retrieves the next row from the cursor into a target The target may be a row variable, a record variable, or a comma-separated list of simple variables, just like SELECT INTO. As with SELECT INTO, the special variable FOUND may be checked to see whether a row was obtained or not. 14. PL/pgSQL CS4222_Su17

13 Fetching from a Cursor FETCH cursor INTO target; Examples:
FETCH curs1 INTO record1; FETCH curs2 INTO v1, v2, v3; 14. PL/pgSQL CS4222_Su17

14 9/21/2018 Cursor example Write a function mean() to compute the average age of sailors.(Do not use avg() ) CREATE FUNCTION mean () RETURNS float8 AS ' DECLARE mean float8 :=0; tempAge int8; count int8 :=0; ages CURSOR for select age from Sailors; BEGIN OPEN ages; Loop FETCH ages into tempAge; Exit when not found; count:=count+1; mean:=mean+tempAge; END loop; CLOSE ages; if count<> 0 then mean := mean/count; return mean; else return -1; end if; END; ' LANGUAGE 'plpgsql'; 14. PL/pgSQL CS4222_Su17

15 PERFORM Use the PERFORM keyword to call a function and ignore its return data Syntax: PERFORM function_identifier(arguments); 14. PL/pgSQL CS4222_Su17

16 PERFORM example CREATE FUNCTION ship_item (text,text,text) RETURNS integer AS ' DECLARE l_name ALIAS FOR $1; f_name ALIAS FOR $2; book_isbn ALIAS FOR $3; -- Declare a variable to hold the book ID number. This variable -- is necessary to check for the existence of the provided ISBN. book_id INTEGER; -- Declare a variable to hold the customer ID number. This variable -- is necessary to check for the existence of the customer. customer_id INTEGER; BEGIN -- Retrieve the customer ID number with a previously created -- function. SELECT INTO customer_id get_customer_id(l_name,f_name); IF customer_id = -1 THEN RETURN -1; END IF; -- Retrieve the ID number of the book with the specified ISBN. SELECT INTO book_id book_id FROM editions WHERE isbn = book_isbn; -- If the book does not exist in the system, return -1. IF NOT FOUND THEN RETURN -1; END IF; -- If the book and customer both exist, add the shipment. PERFORM add_shipment(customer_id,book_isbn); -- Return 1 to indicate the function was successful. RETURN 1; END; ' LANGUAGE 'plpgsql'; 14. PL/pgSQL CS4222_Su17

17 What is a trigger? A trigger is a specification that the database should automatically execute a particular function whenever a certain type of operation is performed Triggers can be defined to execute either before or after any INSERT, UPDATE, or DELETE operation, either once per modified row, or once per SQL statement. If a trigger event occurs, the trigger's function is called at the appropriate time to handle the event 14. PL/pgSQL CS4222_Su17

18 Motivation Maintain database integrity Some applications of triggers :
Constraints embedded in SQL (e.g., referential integrity constraints and CHECK constraints) are not omni capable Some applications of triggers : Maintaining functional dependencies (e.g. in BCNF) Keeping referential integrities for specialization/generalization hierarchies To enforce business rules, e.g., Give a customer additional discount if he has made enough purchase in the past month A bank deals with overdrafts by setting the account balance to 0 and creating a loan in the amount of the overdraft These business rules could also be implemented on application level The choice whether a rule is implemented in application or in database is a design issue 14. PL/pgSQL CS4222_Su17

19 Design a trigger Create a trigger function
Specify the actions to be taken when the trigger is invoked Use CREATE TRIGGER to create a trigger Specify the events that invoke the trigger Insert, delete, update The trigger function must be created before the trigger is created 14. PL/pgSQL CS4222_Su17

20 Create Triggers CREATE TRIGGER name
{ BEFORE | AFTER } { event [ OR ... ] } ON table [ FOR [ EACH ] { ROW | STATEMENT } ] EXECUTE PROCEDURE function_name ( ) 14. PL/pgSQL CS4222_Su17

21 Options: The Condition
AFTER/BEFORE Determine whether the function is called before or after the event Three events INSERT/DELETE/UPDATE. UPDATE can be UPDATE ON a particular attribute Use OR to connect multiple events A trigger can only be set on the entire table (in PostgreSQL) Cannot set triggers on columns 14. PL/pgSQL CS4222_Su17

22 Before/After triggers
Before triggers The trigger function is run before the triggering statement completes (INSERT, UPDATE, DELETE) Eliminate unnecessary processing of the triggering statement After triggers The trigger function is called after the trigger statement completes If an exception is raised in the trigger function, the trigger statement is canceled 14. PL/pgSQL CS4222_Su17

23 Trigger level Triggers are either row-level or statement-level.
FOR EACH ROW indicates row-level; its absence indicates statement-level. Row level triggers are executed once for each modified tuple. Statement-level triggers execute once for an SQL statement regardless of how many tuples are modified. 14. PL/pgSQL CS4222_Su17

24 Trigger Type Combinations
BEFORE statement trigger Before executing the triggering statement, the trigger action is run. BEFORE row trigger Before modifying each row affected by the triggering statement and before checking appropriate integrity constraints, the trigger action is run, if 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 run for the current row provided the trigger restriction was not violated. AFTER statement trigger After executing the triggering statement and applying any deferred integrity constraints, the trigger action is run 14. PL/pgSQL CS4222_Su17

25 Order of Execution Execute any BEFORE STATEMENT trigger on table
For each row affected by statement Execute any BEFORE ROW level trigger Execute command (INSERT DELETE UPDATE) Apply referential integrity constraints (ON DELETE, ON UPDATE) Execute any AFTER ROW level trigger Execute any AFTER STATEMENT trigger on table 14. PL/pgSQL CS4222_Su17

26 CREATE Trigger examples
CREATE TRIGGER emp_stamp BEFORE INSERT OR UPDATE ON emp FOR EACH ROW EXECUTE PROCEDURE emp_stamp(); Example 2 CREATE TRIGGER check_shipment BEFORE INSERT OR UPDATE ON Shipments FOR EACH ROW EXECUTE PROCEDURE check_shipment_addition(); 14. PL/pgSQL CS4222_Su17

27 Trigger functions CREATE OR REPLACE FUNCTION funcname ( ) RETURNS TRIGGER AS ' –- Always return trigger! {[DECLARE <variable name> <variable type]}…; --Local variables BEGIN <function body> RETURN <retvalue>; END; ' LANGUAGE 'plpgsql'; 14. PL/pgSQL CS4222_Su17

28 About Trigger funtions
Must be defined before the trigger is created Must be declared as no parameter and return a trigger type Return NULL, or the tuple to be modified Every trigger function created has access to a number of special variables that exist to provide information about the calling trigger, and to allow the trigger function to manipulate table data. 14. PL/pgSQL CS4222_Su17

29 Special Variables NEW OLD
denotes table/row AFTER operation (update/insert/delete) is executed OLD denotes table/row BEFORE operation (update/insert/delete) is executed NEW and OLD are similar to THIS pointer in C++; For DELETE triggers we’ll use OLD, since after deletion NEW is empty 14. PL/pgSQL CS4222_Su17

30 Other Special Variables Accessible in Triggered Function
Name Meaning Allowed values TG_NAME Trigger name string TG_WHEN Trigger action time BEFORE or AFTER TG_LEVEL Level of triggered action ROW or STATEMENT TG_OP Trigger event INSERT, UPDATE or DELETE TG_RELNAME Name of table on which trigger is executed String TG_RELID Object ID of triggered table Integer TG_NARGS Number of arguments of triggered function 14. PL/pgSQL CS4222_Su17

31 Trigger function example
CREATE FUNCTION check_shipment_addition () RETURNS trigger AS ' DECLARE id_number INTEGER; book_isbn TEXT; BEGIN SELECT id INTO id_number FROM customers WHERE id = NEW.customer_id; IF NOT FOUND THEN RAISE EXCEPTION ''Invalid customer ID number.''; END IF; SELECT isbn INTO book_isbn FROM editions WHERE isbn = NEW.isbn; IF NOT FOUND THEN RAISE EXCEPTION ''Invalid ISBN.''; END IF; -- If the previous checks succeeded, update the stock amount. IF TG_OP = ''INSERT'' THEN UPDATE stock SET stock = stock -1 WHERE isbn = NEW.isbn; END IF; RETURN NEW; END; ' LANGUAGE 'plpgsql'; 14. PL/pgSQL CS4222_Su17

32 A complete example This example trigger ensures that any time a row is inserted or updated in the employee table, the current user name and time are stamped into the row. It also checks that an employee's name is given and that the salary is a positive value. 14. PL/pgSQL CS4222_Su17

33 A complete example CREATE TABLE emp ( empname text; salary integer,
last_date timestamp, last_user text ); CREATE TRIGGER emp_stamp BEFORE INSERT OR UPDATE ON emp FOR EACH ROW EXECUTE PROCEDURE emp_stamp(); 14. PL/pgSQL CS4222_Su17

34 A complete example CREATE FUNCTION emp_stamp() RETURNS trigger AS '
BEGIN -- Check that empname and salary are given IF NEW.empname IS NULL THEN RAISE EXCEPTION ''empname cannot be null''; END IF; IF NEW.salary IS NULL THEN RAISE EXCEPTION ''% cannot have null salary'', NEW.empname; END IF; IF NEW.salary < 0 THEN RAISE EXCEPTION ''% cannot have a negative salary'', NEW.empname; NEW.last_date := ''now''; NEW.last_user := current_user; RETURN NEW; END; ' LANGUAGE plpgsql; 14. PL/pgSQL CS4222_Su17

35 Another trigger example
Create a function for states that uses the new RECORD variable to perform the following actions: Reject a state code that is not exactly two alphabetic characters Reject a state name that contains nonalphabetic characters Reject a state name less than three characters in length Uppercase the state code Capitalize the state name 14. PL/pgSQL CS4222_Su17

36 Example Function CREATE TABLE statename ( code text, name text )
CREATE FUNCTION trigger_insert_update_statename() RETURNS trigger AS ' BEGIN IF new.code !~ ''^[A-Z|a-z][A-Z|a-z]$'' THEN RAISE EXCEPTION ''State code must be two alphabetic characters.''; END IF; IF new.name !~ ''^[A-Z|a-z ]*$'' THEN RAISE EXCEPTION ''State name must be only alphabetic characters.''; IF length(trim(new.name)) < 3 THEN RAISE EXCEPTION ''State name must longer than two characters.''; new.code := upper(new.code); -- uppercase statename.code new.name := initcap(new.name); -- capitalize statename.name RETURN new; END; ' LANGUAGE 'plpgsql'; 14. PL/pgSQL CS4222_Su17

37 Example Trigger CREATE TRIGGER trigger_statename
BEFORE INSERT OR UPDATE ON statename FOR EACH ROW EXECUTE PROCEDURE trigger_insert_update_statename(); 14. PL/pgSQL CS4222_Su17

38 Example Execution INSERT INTO statename VALUES ('a', 'alabama');
INSERT INTO statename VALUES ('al', 'alabama2'); INSERT INTO statename VALUES ('al', 'al'); INSERT INTO statename VALUES ('al', 'alabama'); 14. PL/pgSQL CS4222_Su17

39 Exercise CREATE TABLE Teach ( fid integer, cid integer, year date ) INSERT INTO Teach VALUES (100, 1111, '2010'); INSERT INTO Teach VALUES (100, 2222, '2010'); INSERT INTO Teach VALUES (200, 3333, '2010'); INSERT INTO Teach VALUES (200, 4444, '2010'); INSERT INTO Teach VALUES (200, 5555, '2010'); Create a trigger to ensure each faculty only teaches no more than 3 courses a year. 14. PL/pgSQL CS4222_Su17


Download ppt "CS4222 Principles of Database System"

Similar presentations


Ads by Google