Triggers
-
A postgresql trigger is a functoin invoked automatically whenever 'an event' associated with a table occurs.
-
An event could be any of the following;
- INSERT
- UDPATE
- DELETE
- TRUNCATE
-
You can associate a trigger with a
- Table
- View
- Foreign Table
-
A trigger is a special 'user-defined function'
- A trigger is automatically invoked
-
We can create a triger
- BEFORE
- Trigger is fired before an event is about to happen
- AFTER
- Trigger is fired after the event is completed
- INSTEAD
- In case the event fails, trigger is fired
- BEFORE
-
Cannot be fired manually
- Fired in alphbetically order
- DO Not change in primary key, foriegn key or unique key column
- DO Not update records in the table that you normally read during the transaction
- DO Not read data from a table that is updating during the same transaction
- DO Not aggregate/summarized over the table that you are updating
Types of Triggers
-
Row level
- If row is marked for
FOR EACH ROW
, then trigger will be called for each row that is getting modfied by the event
- If row is marked for
-
Statement level
- The
FOR EACH STATEMENT
will call the trigger function only ONCE for each statement, regardless of the number of rows getting modified.
- The
When | Event | Row-level | Statement-level |
---|---|---|---|
INSERT/UDPATE/DELETE | Tables | Tables and view | |
before | Truncate | ||
---------- | -------------------- | --------- | --------------- |
INSERT/UDPATE/DELETE | Tables | Tables and view | |
AFTER | Truncate | ||
---------- | -------------------- | --------- | --------------- |
INSERT/UDPATE/DELETE | Views | ||
INSTEAD OF | Truncate |
Create your own Trigger in PostgreSQL
CREATE FUNCTION trigger_function( )
RETURNS TRIGGER LANGUAGE PLPGSQL
AS $$
BEGIN
-- TRIGGER LOGIC
END;
$$
Syntax
CREATE TRIGGER trigger_name {BEFORE|AFTER} {EVENT}
ON table_name
[FOR [EACH] {ROW | STATEMENT}]
EXECUTE PROCEDURE trigger_function
-- FOR EACH [ROW|STATEMENT]
Data Auditing with Triggers
Setup Example tables
CREATE TABLE players (
player_id SERIAL PRIMARY KEY,
name VARCHAR(100)
);
CREATE TABLE player_audits (
player_audit_id SERIAL PRIMARY KEY,
player_id INT NOT NULL,
name VARCHAR(100) NOT NULL,
new_name VARCHAR(100) NOT NULL,
edit_date TIMESTAMP NOT NULL
);
Setup Function to TRIGGER
-- Function executed by TRIGGER
CREATE OR REPLACE FUNCTION fn_players_name_changes_log()
RETURNS TRIGGER
LANGUAGE PLPGSQL
AS
$$
BEGIN
IF NEW.name <> OLD.name THEN
INSERT INTO player_audits
( player_id, name, new_name, edit_date )
values ( OLD.player_id, OLD.name, NEW.name ,NOW() );
END IF;
RETURN NEW;
END;
$$
-- TRIGGER Definition
CREATE TRIGGER trg_players_name_changes
BEFORE UPDATE
ON players
FOR EACH ROW
EXECUTE PROCEDURE fn_players_name_changes_log();
DML to fire above trigger
INSERT INTO players (name) VALUES ('UDAY'),('YADAV');
SELECT * FROM players;
select * from player_audits;
UPDATE players
SET name = 'UDAY 2'
WHERE player_id = 2;
Another Trigger Example
-- create table for example
CREATE TABLE t_temperature_log (
id_temperature SERIAL PRIMARY KEY,
add_date TIMESTAMP,
temperature NUMERIC
);
-- create function for trigger to execute
CREATE OR REPLACE FUNCTION fn_temperature_value_check_at_insert()
RETURNS TRIGGER
LANGUAGE PLPGSQL
AS
$$
BEGIN
IF NEW.temperature < -30 then
NEW.temperature = 0;
END IF;
RETURN NEW;
END;
$$
-- creating trigger
CREATE TRIGGER trg_temperature_value_check_at_insert
BEFORE INSERT
ON t_temperature_log
FOR EACH ROW
EXECUTE PROCEDURE fn_temperature_value_check_at_insert();
-- Queries
INSERT INTO t_temperature_log ( add_date, temperature )
values ( '2020-10-01' , 10 );
select * from t_temperature_log;
INSERT INTO t_temperature_log ( add_date, temperature )
values ( '2020-10-01' , -33 );
select * from t_temperature_log;