📜  PostgreSQL-触发器

📅  最后修改于: 2020-11-26 06:30:19             🧑  作者: Mango


PostgreSQL触发器是数据库回调函数,当发生指定的数据库事件时,它们会自动执行/调用。

以下是有关PostgreSQL触发器的要点-

  • 可以指定PostgreSQL触发器来触发

    • 在尝试对该行进行操作之前(在检查约束并尝试执行INSERT,UPDATE或DELETE之前)

    • 操作完成后(检查约束并完成INSERT,UPDATE或DELETE之后)

    • 代替操作(在视图上进行插入,更新或删除的情况下)

  • 标记为FOR EACH ROW的触发器将为该操作修改的每一行调用一次。相反,标记为FOR STATE STATEMENT的触发器对于任何给定操作仅执行一次,无论其修改了多少行。

  • WHEN子句和触发操作都可以使用形式为NEW.column-nameOLD.column-name的引用来访问要插入,删除或更新的行的元素,其中column-name是来自以下位置的列的名称与触发器关联的表。

  • 如果提供了WHEN子句,则仅对WHEN子句为true的行执行指定的PostgreSQL语句。如果未提供WHEN子句,则对所有行执行PostgreSQL语句。

  • 如果为同一事件定义了多个相同种类的触发器,则将按名称的字母顺序触发它们。

  • BEFORE,AFTER或INSTEAD OF关键字确定何时相对于关联行的插入,修改或删除执行触发动作。

  • 触发器与其关联的表被删除时,触发器将被自动删除。

  • 要修改的表必须与触发器附加到的表或视图位于同一数据库中,并且必须仅使用表名,而不能使用database.tablename

  • 如果指定了CONSTRAINT选项,则会创建约束触发器。除了可以使用SET CONSTRAINTS调整触发器触发的时间外,这与常规触发器相同。当违反约束触发器实现的约束时,预计将引发异常。

句法

创建触发器的基本语法如下:

CREATE  TRIGGER trigger_name [BEFORE|AFTER|INSTEAD OF] event_name
ON table_name
[
 -- Trigger logic goes here....
];

在这里, event_name可以是对提到的表table_name的INSERT,DELETE, UPDATETRUNCATE数据库操作。您可以选择在表名称后指定FOR EACH ROW。

以下是在表的一个或多个指定列上的UPDATE操作上创建触发器的语法,如下所示-

CREATE  TRIGGER trigger_name [BEFORE|AFTER] UPDATE OF column_name
ON table_name
[
 -- Trigger logic goes here....
];

让我们考虑一种情况,在这种情况下,我们希望对COMPANY表中插入的每个记录进行审计试用,我们将如下创建新记录(如果已有的话,请删除COMPANY表)。

testdb=# CREATE TABLE COMPANY(
   ID INT PRIMARY KEY     NOT NULL,
   NAME           TEXT    NOT NULL,
   AGE            INT     NOT NULL,
   ADDRESS        CHAR(50),
   SALARY         REAL
);

为了保持审计试用状态,我们将创建一个名为AUDIT的新表,只要在COMPANY表中有新记录的条目,就会插入日志消息-

testdb=# CREATE TABLE AUDIT(
   EMP_ID INT NOT NULL,
   ENTRY_DATE TEXT NOT NULL
);

在这里,ID是AUDIT记录ID,EMP_ID是ID,它将来自COMPANY表,当在COMPANY表中创建记录时DATE将保留时间戳。现在,让我们在COMPANY表上创建触发器,如下所示:

testdb=# CREATE TRIGGER example_trigger AFTER INSERT ON COMPANY
FOR EACH ROW EXECUTE PROCEDURE auditlogfunc();

其中auditlogfunc()是PostgreSQL过程,具有以下定义-

CREATE OR REPLACE FUNCTION auditlogfunc() RETURNS TRIGGER AS $example_table$
   BEGIN
      INSERT INTO AUDIT(EMP_ID, ENTRY_DATE) VALUES (new.ID, current_timestamp);
      RETURN NEW;
   END;
$example_table$ LANGUAGE plpgsql;

现在,我们将开始实际的工作。让我们开始在COMPANY表中插入记录,这将导致在AUDIT表中创建审核日志记录。因此,让我们在COMPANY表中创建一条记录,如下所示-

testdb=# INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (1, 'Paul', 32, 'California', 20000.00 );

这将在COMPANY表中创建一条记录,如下所示-

id | name | age | address      | salary
----+------+-----+--------------+--------
  1 | Paul |  32 | California   |  20000

同时,将在AUDIT表中创建一条记录。该记录是触发器的结果,该触发器是我们在COMPANY表上的INSERT操作上创建的。同样,您可以根据需要在UPDATE和DELETE操作上创建触发器。

emp_id |          entry_date
--------+-------------------------------
      1 | 2013-05-05 15:49:59.968+05:30
(1 row)

列出触发器

您可以从pg_trigger表中列出当前数据库中的所有触发器,如下所示:

testdb=# SELECT * FROM pg_trigger;

上面给出的PostgreSQL语句将列出所有触发器。

如果要列出特定表上的触发器,则将AND子句与表名一起使用,如下所示:

testdb=# SELECT tgname FROM pg_trigger, pg_class WHERE tgrelid=pg_class.oid AND relname='company';

上面给出的PostgreSQL语句还将仅列出以下一项-

tgname
-----------------
 example_trigger
(1 row)

下降触发

以下是DROP命令,可用于删除现有触发器-

testdb=# DROP TRIGGER trigger_name;