如果其中一列已更改,则会触发PostgreSQL

时间:2016-09-19 14:00:55

标签: postgresql triggers

如果至少有一个字段发生了更改,我希望跟踪表上的更改并在发生UPDATE后将它们存储在相应的历史记录表中。

我有以下表格:

tbl_employees

CREATE TABLE tbl_employees (
    id serial NOT NULL,
    first_name character varying NOT NULL,
    last_name character varying NOT NULL
)

tbl_employees_history

CREATE TABLE tbl_employees (
    id serial NOT NULL,
    employee_id NOT NULL,
    first_name character varying NOT NULL,
    last_name character varying NOT NULL,
    changed_on timestamp NOT NULL
)

功能

CREATE OR REPLACE FUNCTION log_employee_changes() RETURNS trigger as 
$BODY$
BEGIN
     IF (NEW.last_name <> OLD.last_name) or (NEW.first_name <> OLD.first_name) THEN
     INSERT INTO tbl_employee_history(employee_id,last_name, first_name,changed_on)
     VALUES(OLD.id,OLD.last_name, OLD.first_name,now());
     END IF;
RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql;

触发

CREATE TRIGGER add_log
BEFORE UPDATE ON tbl_employees
FOR EACH ROW
EXECUTE PROCEDURE log_employee_changes();

到目前为止,这件事情很有效。但是我想知道我是否有一个表可以说15列,如果其中一列已更改,我想保存历史记录。我是否必须为每个字段反复重复IF语句,或者是否有某种技巧可以检查每一列?这样我就可以在表格中添加一列而不会忘记更改触发功能。

这样的事情:

CREATE OR REPLACE FUNCTION log_employee_changes() RETURNS trigger as 
$BODY$
BEGIN
     IF ?????there is one change on whatever column????? THEN
     INSERT INTO tbl_employee_history(employee_id,last_name, first_name,changed_on)
     VALUES(OLD.id,OLD.last_name, OLD.first_name,now());
     END IF;
RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql;

2 个答案:

答案 0 :(得分:3)

您可以比较整个记录:

if new <> old then ...

if new is distinct from old then ...

第二种选择更为通用。仅当您确定记录不能包含空值时才使用第一个。

答案 1 :(得分:1)

我希望,这会对你有所帮助:

CREATE OR REPLACE FUNCTION log_employee_changes() RETURNS trigger as 
$BODY$
BEGIN
     IF OLD!=NEW THEN
     INSERT INTO tbl_employee_history(employee_id,last_name, first_name,changed_on)
     VALUES(OLD.id,OLD.last_name, OLD.first_name,now());
     END IF;
RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql;