Presentation is loading. Please wait.

Presentation is loading. Please wait.

User Defined Functions and Triggers Tutorial

Similar presentations


Presentation on theme: "User Defined Functions and Triggers Tutorial"— Presentation transcript:

1 User Defined Functions and Triggers Tutorial

2 Plan for UDF and PL/ pgSQL
Syntax of a UDF SQL UDFs and tables Procedural Language / PosgreSQL (PL/pgSQL) Special Features of PL/pgSQL SELECT … INTO … FOUND RAISE The Special TRIGGER Syntax Reading: PostgreSQL Documentation

3 The Basic PostgreSQL UDF Syntax
CREATE [ OR REPLACE ] FUNCTION name ( [ [ argmode ] [ argname ] argtype [, ...] ] ) [ RETURNS rettype ] AS 'definition' LANGUAGE langname argmode is one of in, out, inout, in is default Use [OR REPLACE] to update the existing function definition

4 Functions in SQL Queries With Tables (1)
A powerful use of functions is in queries that retrieve data from tables CREATE TABLE Rectangle (RectId int, a real, b real); INSERT INTO Rectangle VALUES(1, 5.5, 6.6); VALUES(2, 3.3, 4.4); RectId a b 1 5.5 6.6 2 3.3 4.4

5 Functions in SQL Queries With Tables (2)
CREATE OR REPLACE FUNCTION area(real, real) RETURNS real AS ‘SELECT $1*$2;’ LANGUAGE SQL; SELECT RectId, area(a, b) as Rec_Area FROM Rectangle; A powerful use of of user defined functions is in queries RectId Rec_Area 1 36.3 2 14.52

6 What is PL/pgSQL PL/pgSQL is a language that combines:
The expressive power of SQL with The more typical features of a procedural programming language: Control structures Special SQL statements (SELECT INTO. . .) It is aimed for: Creating user defined functions Creating trigger procedures Efficient execution (vaguely speaking it is precompiled) Easy of use PL/pgSQL handler parses the function and produces an internal binary instruction tree the first time the function is called, but SQL expressions and commands are translated when they are used for the first time in the function. Each subsequent visit to that expression or command uses the prepared execution plan.

7 SELECT INTO The result of a SELECT command yielding multiple columns (but only one row) can be assigned to a record variable SELECT <attrbute_list> INTO <target> FROM … If the type of target is record, target automatically configures to the query result If the result is empty, target will be (, …, ) a structure with null components If a SELECT command returns multiple rows only the first one retrieved is assigned to the target

8 A SELECT. . . INTO Example CREATE FUNCTION ft() RETURNS record AS $$ DECLARE RecordVar Record; BEGIN SELECT * INTO RecordVar FROM "Sailors" where rating = 5; IF RecordVar.rating IS NULL THEN RAISE NOTICE 'There is no Sailors with rating = 5'; RETURN NULL; ELSE RETURN RecordVar; END IF; END; $$ LANGUAGE plpgsql; This program was tested

9 Obtaining the Result Status (FOUND )
To determine the result of a command, you can check a special variable named FOUND of the type boolean The following commands set FOUND: SELECT…INTO… sets it true if it returns any row, false otherwise PERFORM sets it true if it returns (and discards) any row, false otherwise UPDATE, INSERT, and DELETE set it true if at least one row is affected, false otherwise FOUND is a local variable within each PL/pgSQL function

10 DROP FUNCTION ft(); SELECT ft();

11 An Example for the FOUND Variable
CREATE FUNCTION ft() RETURNS record AS $$ DECLARE t record; BEGIN SELECT * INTO t FROM Grades WHERE StudentId = 7007 AND CourseId = ‘COMP302’; IF NOT FOUND THEN SELECT * INTO t FROM Student WHERE StudentId = 7007; END IF; RETURN t; END; This program was tested

12 RAISE Statement Even though PL/pgSQL doesn’t offer a way to intercept errors, the RAISE statement is provided to raise an error Syntax: RAISE severity ‘message’ [, variable []]; where severity can be: DEBUG NOTICE – just to send a message to the client application EXCEPTION – to raise an exception, which is handled as described in the manual

13 A RAISE NOTICE Example DECLARE s record; BEGIN SELECT * INTO s FROM Student; IF NOT FOUND THEN RAISE NOTICE 'Table is empty'; RETURN null; ELSE RETURN s; END IF; END; It was checked

14 Triggers

15 Triggers - Motivation Motivation:
Events, like updates made to database relations may provoke some actions to be undertaken afterwards or even before Examples: After recording the pass of an exam, the number of points in student’s record should be augmented appropriately When the number of points scored becomes equal to or greater than 360, student’s data should be recorded in the Graduation table Before a new tuple is inserted, the referential integrity constraint should be check Instead of embedding commands to monitor events in each program that updates a table, an appropriate trigger is associated with the table and executed automatically whenever event occurs

16 Triggers and DBMS Vendors
Many major DBMS vendors introduced triggers during ninetieth The SQL Standard:1999 requires support of triggers

17 Triggers and Active Databases
Active databases are founded on the use of active rules Active rules are most often implemented by triggers A trigger is a program that is invoked as an answer to a situation A situation may be a certain database state or an event A DBMS monitors situations and invokes triggers Users may be unaware of trigger existence

18 Trigger Layout INSERT BEFORE CREATE TRIGGER <trigger_name>
UPDATE AFTER DELETE OR FOR EACH ROW <table_name> ON FOR EACH STATEMENT EXECUTE PROCEDURE <function_name> ( <arguments> );

19 Main Entries of a Trigger
A trigger definition contains the following main entries: Triggering time; before or after the triggering event(s), Event – a change to the database that activates the trigger, Name of the table where the event is monitored, Specification of whether the trigger should fire for each row affected, or only once per a SQL statement that caused the firing Action – the trigger procedure (user defined function) Each trigger responds to given events only An event may be one of the following SQL statement on the table specified: INSERT, DELETE, or UPDATE

20 Timing of the Action An important issue is when the action part of the trigger is going to be executed: Before the activating event, or After the activating event For example: A trigger that maintains referential integrity constraint makes sense to execute before a tuple is inserted, or deleted A trigger that monitors the number of students enrolled in a school should be executed after successful insertion of a new enrollment tuple

21 Before and After Triggers
Before triggers don’t see the final value of the row affected by After triggers see the final value of the row affected by Typically, row before triggers are used for checking or modifying data that will be inserted or updated row after triggers are mostly sensibly used to propagate updates to other tables, or make consistency checks against tables

22 Row and Statement Level Triggers
A trigger may be declared either as a: statement (default), or row trigger A statement trigger is executed only ones per an invocation A row trigger is executed once for each tuple spanned by a triggering statement for which the trigger is fired

23 The Action of a Trigger Generally, a trigger action is either a sequence of SQL statements, or a database transaction program, or an external program In PostrgeSQL environment a trigger action is a special UDF that can be written in PL/pg SQL, or some other procedural languages like C

24 The Trigger Syntax <trigger>::= CREATE TRIGER <trigger_name> {AFTER | BEFORE} <triggering_event> [OR...] ON <table_name> [FOR [EACH] { ROW | STATEMENT }] EXECUTE PROCEDURE <function_name>(arguments); <triggering_events>::= <triggering_event> [OR <triggering_event>…..] <triggering_event>::= {INSERT | DELETE | UPDATE}

25 Trigger Procedures in PL/pg SQL
A trigger procedure is created with CREATE FUNCTION command, which: Does not have any parameters, and Has a trigger return type When a PL/pgSQL function is called as a trigger, several special variables are created automatically in the top level block

26 Automatically Created Variables
The most important automatically created variables: NEW of data type RECORD holding the new database row for INSERT/UPDATE operations in row-level triggers OLD of data type RECORD holding the old database row for UPDATE/DELETE operations in row-level triggers

27 RETURN Type A trigger has to return: The return value of a:
Either NULL, or A record/row value having exactly the structure of the table the trigger was fired for The return value of a: BEFORE or AFTER per-statement trigger, or An AFTER row-level trigger is always ignored Both should be NULL But they can still abort an entire operation by raising en error

28 Returning a Value Being Not NULL
A row level trigger fired BEFORE may return NULL to signal the trigger manager to skip the rest of operations for this row (INSERT/DELETE/UPDATE will not be executed for this row) If a BEFORE row level trigger returns a non null row value, the operation proceeds with that row value

29 Triggers – Example (1) Consider the following part of a relational database schema: Student (StudId, Name, NoOfPts, Degree) Exam (StudId, CourseId, Term, Grade) Example 1: Referential Integrity

30 Example (1) : Tables CREATE TABLE Student ( StudId integer, Name character varying(25), NoOfPts real, Degree character(2), PRIMARY KEY (StudId) ); CREATE TABLE Exam ( CourseId integer, Term character(2), Grade character(1), PRIMARY KEY (StudId,CourseId) );

31 Example (1) : Referential Integrity Trigger - INSERT
CREATE TRIGGER ins_ref_int BEFORE INSERT ON Exam FOR EACH ROW EXECUTE PROCEDURE ins_ref_int(); CREATE OR REPLACE FUNCTION ins_ref_int() RETURNS trigger AS $$ DECLARE s RECORD; BEGIN SELECT * INTO s FROM Student WHERE NEW.StudId = StudId; IF NOT FOUND THEN RAISE NOTICE 'There is no student %', NEW.StudId; RETURN NULL; ELSE RETURN NEW; END IF; END; $$ LANGUAGE PLpgSQL;

32 Triggers - Example (2) : Consider the following part of a relational database schema: Student (StudId, Name, NoOfPts, Degree) Exam (StudId, CourseId, Term, Grade) Example 2: Suppose Grade is NOT NULL Suppose all courses are worth 15 points Whenever a student passes a course, 15 points is added to her/his NoOfPts

33 Example (2) : Add_Points Trigger
CREATE TRIGGER add_points AFTER INSERT ON Exam FOR EACH ROW EXECUTE PROCEDURE add_points(); CREATE OR REPLACE FUNCTION add_points() RETURNS trigger AS $$ BEGIN IF (NEW.Grade < ‘D’) THEN UPDATE Student SET NoOfPts = NoOfPts + 15 WHERE StudId = NEW.StudId; END IF; RETURN NULL; END; $$ LANGUAGE PLpgSQL;

34 Triggers – Potentials and Pitfalls
Triggers have great potential to simplify database system development, because they relay on object-oriented features like encapsulation and message exchange But, it is quite difficult to verify that a set of rules is consistent (i.e. that there are no two rules in the set that contradict each other) It is also hard to guarantee termination of a set of rules

35 A Question for You Is there anything wrong with the following two triggers: CREATE TRIGGER t1 AFTER INSERT ON table1 FOR EACH ROW EXECUTE PROCEDURE update_table_2(); CREATE TRIGGER t2 AFTER UPDATE ON table2 FOR EACH ROW EXECUTE PROCEDURE insert_into_table_1(); Rules t1 and t2 once triggered will continue to trigger each other indefinitely, hence this set of rules will never terminate

36 Example (3) : Definition
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

37 Example (3) : Table CREATE TABLE statename ( code character(5), name character(15), PRIMARY KEY (code) );

38 Example (3) : Function CREATE FUNCTION trigger_insert_update_statename() RETURNS trigger AS $$ BEGIN IF new.code !~ ‘[A-Za-z][A-Za-z]’ THEN RAISE EXCEPTION 'State code must be two alphabetic characters.'; END IF; IF new.name !~ ‘[A-Za-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;

39 Example (3) : Trigger CREATE TRIGGER trigger_statename BEFORE INSERT OR UPDATE ON statename FOR EACH ROW EXECUTE PROCEDURE trigger_insert_update_statename() ;

40 Example (3) : Execution INSERT INTO statename VALUES ('a', 'alabama'); ERROR: State code must be two alphabetic characters. INSERT INTO statename VALUES ('al', 'alabama2'); ERROR: State name must be only alphabetic characters. INSERT INTO statename VALUES ('al', 'al'); ERROR: State name must longer than two characters. INSERT INTO statename VALUES ('al', 'alabama'); INSERT SELECT * FROM statename; code | name AL | Alabama (1 row)

41 Summary PL/pgSQL is a simple block structured language that combines procedural constructs with SQL statements It is designed to provide for: Creating user defined functions Creating trigger procedures Triggers are active rules that are automatically fired when an event occurs In the PostgreSQL environment triggers use PL/pgSQL procedures Triggers are extensively used to implement constraints

42 Summary Active databases react automatically on certain events by activating triggers Structure of a trigger encompass: Timing of the trigger (BEFORE or AFTER) Event that fires the trigger (INSERT, or DELETE, or UPDATE), Scope (FOR EACH ROW, or STATEMENT) Monitored table, and Action that actually enforces some business or integrity rules Action programs are server side functions


Download ppt "User Defined Functions and Triggers Tutorial"

Similar presentations


Ads by Google