Introduction to triggers

download Introduction to triggers

If you can't read please download the document

Transcript of Introduction to triggers

Introduction to Triggers

Robert Haas
PostgreSQL East 2010

What Is a Trigger?

Way to execute a database function automatically.

Can fire on INSERT or UPDATE or DELETE or any combination.

Can fire once per statement or for every row.

Can fire BEFORE or AFTER the main operation.

Example #1: Compute full name

CREATE TABLE person (id serial PRIMARY KEY,first_name varchar not null,middle_name varchar not null,last_name varchar not null,full_name varchar not null);

CREATE OR REPLACE FUNCTION compute_person_full_name() RETURNS trigger AS $$BEGINNEW.full_name := NEW.first_name ||CASE WHEN NEW.middle_name = '' THEN ''ELSE ' ' || NEW.middle_name END || ' ' ||NEW.last_name;RETURN NEW;END$$ LANGUAGE plpgsql;

Example #1: Compute full name

CREATE TRIGGER compute_person_full_nameBEFORE INSERT OR UPDATE ON personFOR EACH ROWEXECUTE PROCEDURE compute_person_full_name();

INSERT INTO person(first_name, middle_name, last_name)VALUES ('Robert', 'M.', 'Haas'),('Tom', '', 'Lane');

rhaas=# select full_name from person; full_name ---------------- Robert M. Haas Tom Lane(2 rows)

Example #2: Counts and sums

CREATE TABLE orders (id serial primary key,customer_name varchar not null,number_of_items integer not null default 0,total_price numeric(12,2) not null default 0);

CREATE TABLE order_items (order_id integer not null references orders (id),item_name varchar not null,price numeric(12,2) not null default 0);

Example #2: Counts and sums

CREATE OR REPLACE FUNCTION update_order_stats()RETURNS trigger AS $$BEGINIF (TG_OP != 'DELETE') THENUPDATE ordersSET number_of_items = number_of_items+ 1, total_price = total_price + NEW.priceWHERE id = NEW.order_id;END IF;IF (TG_OP != 'INSERT') THENUPDATE ordersSET number_of_items = number_of_items- 1, total_price = total_price - OLD.priceWHERE id = OLD.order_id;END IF;RETURN NULL;END$$ LANGUAGE plpgsql;

Example #2: Counts and sums

CREATE TRIGGER update_order_statsAFTER INSERT OR UPDATE OR DELETE ON order_itemsFOR EACH ROWEXECUTE PROCEDURE update_order_stats();

Example #3: Denormalization

CREATE TABLE person (id serial primary key,full_name varchar not null,is_project_manager boolean not null);

CREATE TABLE project (id serial primary key,name varchar not null,project_manager_id integer not nullreferences person (id)
);

Example #3: Denormalization

CREATE TABLE person (id serial primary key,full_name varchar not null,is_project_manager boolean not null);

CREATE TABLE project (id serial primary key,name varchar not null,project_manager_id integer not nullreferences person (id),is_project_manager boolean not null,CONSTRAINT pm_is_legal CHECK (is_project_manager)
);

Example #3: Denormalization

CREATE OR REPLACE FUNCTION project_insert_or_update() RETURNS trigger AS $$BEGINSELECT pp.is_project_manager FROM person ppWHERE pp.id = NEW.project_manager_id FOR UPDATEINTO NEW.is_project_manager;RETURN NEW;END$$ LANGUAGE plpgsql;
CREATE TRIGGER project_insert_or_updateBEFORE INSERT OR UPDATE ON projectFOR EACH ROWEXECUTE PROCEDURE project_insert_or_update();

Example #3: Denormalization

CREATE OR REPLACE FUNCTION person_update() RETURNS trigger AS $$BEGINIF (OLD.is_project_manager IS DISTINCT FROMNEW.is_project_manager) THENUPDATE projectSET is_project_manager =NEW.is_project_managerWHERE project_manager_id = NEW.id;END IF;RETURN NULL;END$$ LANGUAGE plpgsql;
CREATE TRIGGER person_updateAFTER UPDATE ON personFOR EACH ROWEXECUTE PROCEDURE person_update();

Questions?

Any questions?