dif*_*ism 16 postgresql triggers plpgsql
我一直在查看postgresql触发器的文档,但它似乎只显示行级触发器的示例,但我找不到语句级触发器的示例.
特别是,如何在单个语句中迭代更新/插入行并不是很清楚,因为它NEW
是针对单个记录的.
Erw*_*ter 17
OLD
并且NEW
未在语句级触发器中定义.每个文件:
NEW
数据类型
RECORD
; 变量为行级触发器中的INSERT
/UPDATE
operations 保存新数据库行.此变量在语句级触发器和DELETE
操作中未分配.
OLD
数据类型RECORD; 在行级触发器中为
UPDATE
/DELETE
operations 保存旧数据库行的变量.此变量在语句级触发器和INSERT
操作中未分配.
大胆强调我的.
那些并不常见.一个有用的示例是在某些DML命令之后发送通知.
这是我使用的简化版本:
-- Generic trigger function, can be used for multiple triggers:
CREATE OR REPLACE FUNCTION trg_notify_after()
RETURNS trigger AS
$func$
BEGIN
PERFORM pg_notify(TG_TABLE_NAME, TG_OP);
RETURN NULL;
END
$func$ LANGUAGE plpgsql;
-- Trigger
CREATE TRIGGER notify_after
AFTER INSERT OR UPDATE OR DELETE ON my_tbl
FOR EACH STATEMENT
EXECUTE PROCEDURE trg_notify_after();
Run Code Online (Sandbox Code Playgroud)
小智 10
好吧,这里有一些语句级触发器的示例。
桌子:
CREATE TABLE public.test (
number integer NOT NULL,
text character varying(50)
);
Run Code Online (Sandbox Code Playgroud)
触发函数:
OLD
和NEW
仍然 ,NULL
返回值也可以一直保留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;
$$;
Run Code Online (Sandbox Code Playgroud)
设置语句级触发器
仅AFTER
且仅支持一个事件。
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();
Run Code Online (Sandbox Code Playgroud)
例子:
INSERT INTO public.test(number, text) VALUES (1, 'a');
Run Code Online (Sandbox Code Playgroud)
=操作:插入=
新:(1,a)
INSERT INTO public.test(number, text) VALUES (2, 'b'), (3, 'b');
Run Code Online (Sandbox Code Playgroud)
=操作:INSERT =
新:(2,b)
新:(3,b)
UPDATE public.test SET number = number + 1 WHERE text = 'a';
Run Code Online (Sandbox Code Playgroud)
=操作:更新=
旧的:(1,a)
新的:(2,a)
UPDATE public.test SET number = number + 10 WHERE text = 'b';
Run Code Online (Sandbox Code Playgroud)
=操作:更新 =
旧的:(2,b)
旧的:(3,b)
新的:(12,b)
新的:(13,b)
DELETE FROM public.test;
Run Code Online (Sandbox Code Playgroud)
=操作:删除 =
旧:(2,a)
旧:(12,b)
旧:(13,b)