Well, here are some examples of statement-level triggers.
Table:
CREATE TABLE public.test (
number integer NOT NULL,
text character varying(50)
);
Trigger function:
OLD
and NEW
are still NULL
The return value can also be always left NULL
.
CREATE OR REPLACE FUNCTION public.tr_test_for_each_statement()
RETURNS trigger
LANGUAGE plpgsql
AS
$$
DECLARE
x_rec record;
BEGIN
raise notice '=operation: % =', TG_OP;
IF (TG_OP = 'UPDATE' OR TG_OP = 'DELETE') THEN
FOR x_rec IN SELECT * FROM old_table LOOP
raise notice 'OLD: %', x_rec;
END loop;
END IF;
IF (TG_OP = 'INSERT' OR TG_OP = 'UPDATE') THEN
FOR x_rec IN SELECT * FROM new_table LOOP
raise notice 'NEW: %', x_rec;
END loop;
END IF;
RETURN NULL;
END;
$$;
Settings statement-level triggers
Only AFTER
and only one event is supported.
CREATE TRIGGER tr_test_for_each_statement_insert
AFTER INSERT ON public.test
REFERENCING NEW TABLE AS new_table
FOR EACH STATEMENT
EXECUTE PROCEDURE public.tr_test_for_each_statement();
CREATE TRIGGER tr_test_for_each_statement_update
AFTER UPDATE ON public.test
REFERENCING NEW TABLE AS new_table OLD TABLE AS old_table
FOR EACH STATEMENT
EXECUTE PROCEDURE public.tr_test_for_each_statement();
CREATE TRIGGER tr_test_for_each_statement_delete
AFTER DELETE ON public.test
REFERENCING OLD TABLE AS old_table
FOR EACH STATEMENT
EXECUTE PROCEDURE public.tr_test_for_each_statement();
Examples:
INSERT INTO public.test(number, text) VALUES (1, 'a');
=operation: INSERT =
NEW: (1,a)
INSERT INTO public.test(number, text) VALUES (2, 'b'), (3, 'b');
=operation: INSERT =
NEW: (2,b)
NEW: (3,b)
UPDATE public.test SET number = number + 1 WHERE text = 'a';
=operation: UPDATE =
OLD: (1,a)
NEW: (2,a)
UPDATE public.test SET number = number + 10 WHERE text = 'b';
=operation: UPDATE =
OLD: (2,b)
OLD: (3,b)
NEW: (12,b)
NEW: (13,b)
DELETE FROM public.test;
=operation: DELETE =
OLD: (2,a)
OLD: (12,b)
OLD: (13,b)