我有以下的表格。
tbl_groups 包含所有当前的数据,当名称改变时,我会将其存储在历史表中。
我还有一个触发器,会将记录写入历史表中。
CREATE TABLE tbl_groups (
id integer NOT NULL,
name varchar NOT NULL,
active boolean NOT NULL
);
CREATE TABLE tbl_groups_history (
id integer NOT NULL,
group_id integer NOT NULL,
name varchar NOT NULL
);
当激活字段为false时,更新操作将无法执行。因此,我创建了一个触发器,在这种情况下抛出异常:
CREATE OR REPLACE FUNCTION fn_group_deny_update_when_inactive() RETURNS TRIGGER AS
$BODY$
BEGIN
IF
OLD.active = false
THEN
RAISE EXCEPTION 'Record is inactive';
END IF;
RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql;
CREATE TRIGGER 01_group_can_update
BEFORE UPDATE ON tbl_groups
FOR EACH ROW
EXECUTE PROCEDURE fn_group_deny_update_when_inactive();
我还有一个触发器,会将记录写入历史表中。
CREATE OR REPLACE FUNCTION fn_group_log_history() RETURNS trigger as
$BODY$
BEGIN
IF
(NEW.name <> OLD.name)
THEN
INSERT INTO tbl_groups_history (group_id, name)
VALUES (OLD.id, OLD.name);
END IF;
RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql;
CREATE TRIGGER 02_group_write_history_log
BEFORE UPDATE ON tbl_groups
FOR EACH ROW
EXECUTE PROCEDURE fn_group_log_history();
我已经以01和02作为前缀命名了触发器,这样我就知道它们将按照PostgreSQL以字母顺序触发的顺序执行。
我对这种方法有一些问题,因为我不确定它是否是良好的实践:
- 是否可能有一个BEFORE UPDATE on tbl_groups触发器来按特定顺序执行这2个函数?
- 是否更好只有一个函数首先检查“active”字段,如果它继续,则进行历史记录处理?所以我将只有1个(更大的)函数和1个触发器。
所有内容都在一个函数中:
CREATE OR REPLACE FUNCTION fn_group_before_update() RETURNS trigger as
$BODY$
BEGIN
IF
OLD.active = false
THEN
RAISE EXCEPTION 'Record is inactive';
END IF;
IF
(NEW.name <> OLD.name)
THEN
INSERT INTO tbl_groups_history (group_id, name)
VALUES (OLD.id, OLD.name);
END IF;
RETURN NEW;
END;
$BODY$
考虑到性能、代码维护等因素,你对此有何想法?