English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

PostgreSQL 基础教程

PostgreSQL 高级教程

PostgreSQL 接口

مكتبات PostgreSQL

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

下面是关于 PostgreSQL 触发器几个比较重要的点:

  • PostgreSQL 触发器可以在下面几种情况下触发:

    • 在执行操作之前(在检查约束并尝试插入、更新或删除之前)。

    • 在执行操作之后(在检查约束并插入、更新或删除完成之后)。

    • 更新操作(在对一个视图进行插入、更新、删除时)。

  • 触发器的 FOR EACH ROW 属性是可选的,如果选中,当操作修改时每行调用一次;相反,选中 FOR EACH STATEMENT,不管修改了多少行,每个语句标记的触发器执行一次。

  • WHEN 子句和触发器操作在引用 NEW.column-name 和 OLD.column-name 表单插入、删除或更新时可以访问每一行元素。其中 column-name 是与触发器关联的表中的列的名称。

  • 如果存在 WHEN 子句,PostgreSQL 语句只会执行 WHEN 子句成立的那一行,如果没有 WHEN 子句,PostgreSQL 语句会在每一行执行。

  • BEFORE 或 AFTER 关键字决定何时执行触发器动作,决定是在关联行的插入、修改或删除之前或者之后执行触发器动作。

  • 要修改的表必须存在于同一数据库中,作为触发器被附加的表或视图,且必须只使用 tablename,而不是 database.tablename。

  • 当创建约束触发器时会指定约束选项。这与常规触发器相同,只是可以使用这种约束来调整触发器触发的时间。当约束触发器实现的约束被违反时,它将抛出异常。

语法

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

CREATE 		TRIGGER 	trigger_name 	[BEFORE|AFTER|INSTEAD 	OF] 	event_name
ON table_name
[
 -- 触发器逻辑....
];

在这里,event_name 可以是在所提到的表 table_name 上的 INSERT、DELETE 和 UPDATE 数据库操作。您可以在表名后选择指定 FOR EACH ROW。

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

CREATE  TRIGGER trigger_name [BEFORE|AFTER] UPDATE OF column_name
ON table_name
[
 -- 触发器逻辑....
];

在线示例

让我们假设一个情况,我们要为被插入到新创建的 COMPANY 表(如果已经存在,则删除重新创建)中的每一个记录保持审计试验:

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

للحفاظ على تجربة التدقيق، سننشئ جدولًا جديدًا يُدعى AUDIT. سيتم إدراج رسائل السجل عند وجود سجل جديد في جدول COMPANY:

w3codeboxdb=# إنشاء جدول AUDIT(
   EMP_ID INT NOT NULL,
   ENTRY_DATE TEXT NOT NULL
);

في هذا السياق، ID هو ID سجل AUDIT، EMP_ID هو ID من جدول COMPANY، DATE سيبقى على نفس التوقيت عند إنشاء السجل في COMPANY. لذا، دعونا ننشئ تنبيهًا على جدول COMPANY كما يلي:

w3codeboxdb=# إنشاء تنبيه example_trigger بعد إدراج على COMPANY لكل سطر تنفيذ إجراء auditlogfunc();

auditlogfunc() هي برنامج في PostgreSQL، و تعريفها كالتالي:

إنشاء أو استبدال الوظيفة auditlogfunc() التي تعود بنوع 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:

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

في هذه الحالة، تم إدراج سجل في جدول COMPANY:

في نفس الوقت، تم إدراج سجل في جدول AUDIT لأننا قمنا بإنشاء trigger عند إدراج جدول COMPANY. بنفس الطريقة، يمكننا إنشاء triggers عند تحديث أو حذف سجلات:

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

إدراج التrigger

يمكنك سحب قائمة بجميع التrigger في قاعدة البيانات الحالية من جدول pg_trigger كالتالي:

w3codeboxdb=# SELECT * FROM pg_trigger;

إذا كنت تريد قائمة بالترiggers الخاصة بالجدول المحدد، فإن الجملة تكون كالتالي:

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

حصلت على النتيجة التالية:

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

حذف الترigger

قواعد الأساس لتحذيف الترigger كالتالي:

drop trigger ${trigger_name} on ${table_of_trigger_dependent};

تعليمات حذف الترigger example_trigger من الجدول company في هذا المقال هي:

drop trigger example_trigger on company;