跳转到主要内容
模块 12 · 第 3 课(共 4)课程中的47/57~15 min
模块课程(3/4)

触发器简介

触发器是一个神奇的盒子(传感器),它在数据中的插入、更新或删除事件之前或之后自动运行一段逻辑。\n不过,在教导表做出反应之前,我们需要给它一个用 PL/pgSQL 编写的特殊“触发器函数”,该函数必须以返回名为“TRIGGER”的合成格式结束。

这些函数不接受括号中的普通参数;相反,他们免费提供神奇的内置对象 NEW 和 OLD ,其中包含传感器正在监视的表中的原始或传入行数据!

SQL
CREATE OR REPLACE FUNCTION audit_deletions()
RETURNS TRIGGER AS $$
BEGIN
  -- OLD.id is magically the id value of the poor record being deleted
  INSERT INTO audit_log (table_name, record_id, action)
  VALUES (TG_TABLE_NAME, OLD.id, 'DELETE');

  RETURN OLD; -- Triggers before a Delete route must grant the exit
END;
$$ LANGUAGE plpgsql;

此过程完成了写入日志的艰苦工作。稍后,在第二步中,它将永久连接到我们想要保护的表的事件。

自己尝试一下

锻炼#sql.m12.l3.e1
尝试:0加载中...

我们需要保护客户:没有人低于 18 岁(我们的虚拟检查),或者,除了虚构的逻辑之外,我们希望强制在 INSERT 时传递的“first_name”字符串始终以大写形式存储在数据库中,忽略任何 JS 客户端格式。\n编写一个名为“force_uppercase_name()”的触发器函数。它不接受 () 参数。\n它返回 TRIGGER。创建正文模板。\n通过魔术赋值“NEW.first_name = UPPER(NEW.first_name);”强制分配整个传入对象。然后返回重塑后的 NEW 变量。

正在加载编辑器...
显示提示

创建或替换函数force_uppercase_name() 返回触发器为$$ BEGIN NEW.first_name = UPPER(NEW.first_name);返回新的;结尾; $$ 语言 plpgsql;

3 次尝试后可用的解决方案

锻炼#sql.m12.l3.e2
尝试:0加载中...

创建一个触发器函数“protect_price_drops()”,阻止攻击者试图以极低的价格购买产品的恶意更新。\n使用“IF NEW.unit_price < OLD.unit_price THEN”之类的逻辑,引发导致一切崩溃的本机异常。\n致命的 PL/pgSQL 异常使用“RAISE EXCEPTION ''Prezzo non abbassabile!'';”的形式。

正在加载编辑器...
显示提示

BEGIN IF NEW.unit_price < OLD.unit_price THEN RAISE EXCEPTION 'Prezzo non abbassabile!';结束如果;返回新的;结尾;

3 次尝试后可用的解决方案