当前位置: 首页 > 知识库问答 >
问题:

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

浦墨竹
2023-03-14

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

我有以下表格:

tbl员工

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个答案

荣晨朗
2023-03-14

希望对您有帮助:

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;
廖弘伟
2023-03-14

您可以比较整个记录:

if new <> old then ...

或者

if new is distinct from old then ...

第二个选项更一般。仅当您确定记录不能包含 null 时,才使用第一个。

 类似资料:
  • 我有一个父组件,在parent.component.html中有以下代码: 在子组件中,我有如下输入参数: 还有一个名为 当父输入被修改时,我希望子输入执行< code>getSpecs()函数。这可能吗?

  • 问题内容: 是否可以在sql中执行更新语句,但仅在更新不同时才执行更新? 例如 如果在数据库中, 不应 执行任何类型的更新 但是,如果 这 应该 执行更新。 问题答案: 使用更新前触发器可以做到这一点。在此触发器中,您可以将旧值与新值进行比较,并在新值不变的情况下取消更新。但这将导致呼叫者网站上的错误。 我不知道为什么要这样做,但是这里有几种可能性: 性能:这里没有性能提升,因为更新不仅需要找到正

  • 以下是我需要更改的一些值: 如果第一列是2= 如果第一列是8= 如果第一列是16= 然而,这个命令并不方便,因为它改变了缩进,并且带有8的行似乎不适合: 输出: 您将如何更正更通用的内容(这意味着即使特定行的缩进不同,它也可以工作),并且不会改变原始文件的缩进?

  • 问题内容: 我有一个postgres数据库,其中包含几个要监视其更新的表,并且如果有任何更新,则要触发“嘿,某些更改”更新。这在基本情况下有效,但是现在是时候进行改进了。 效果很好。我将其附着在桌子上,如下所示: (作为一个附带的问题:如果有比触发函数中的mess’o’$$更好/更容易的方法来对触发结果进行json.stringify的字符串化,请让我知道。平衡引号并不有趣)。 我要执行的操作是将

  • 问题内容: 在oracle中,我可以指定列,这将引发触发器的触发: 现在,我想执行以下操作:当 只 更新 一 列时,我不希望触发触发器。这怎么可能? 我可以列出除那一列之外的所有列,该列不应引起触发器的触发。对于具有许多列的表而言,这非常麻烦。 另一种方法是使用像这样的UPDATING函数: 但是,如果我立即更改了COL1 和 COL3,则该语句的计算结果为false。那不是我想要的,因为我只想更

  • 问题内容: 仅在真正更改数据的情况下,才有可能使用“更新后”触发器。我知道“新旧”。但是使用它们时,我只能比较列。例如“ NEW.count <> OLD.count”。 但我想要类似的东西:如果“ NEW <> OLD”,则运行触发器 一个例子: 关键是,有一个更新,但是 什么都没有改变 。但是无论如何,触发器都在运行。恕我直言,应该有一个没有的方法。 我知道我可以使用 如果现在b <> OLD