模块课程(3/4)
触发器简介
触发器是一个神奇的盒子(传感器),它在数据中的插入、更新或删除事件之前或之后自动运行一段逻辑。\n不过,在教导表做出反应之前,我们需要给它一个用 PL/pgSQL 编写的特殊“触发器函数”,该函数必须以返回名为“TRIGGER”的合成格式结束。
这些函数不接受括号中的普通参数;相反,他们免费提供神奇的内置对象 NEW 和 OLD ,其中包含传感器正在监视的表中的原始或传入行数据!
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;此过程完成了写入日志的艰苦工作。稍后,在第二步中,它将永久连接到我们想要保护的表的事件。
自己尝试一下
我们需要保护客户:没有人低于 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 次尝试后可用的解决方案
创建一个触发器函数“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 次尝试后可用的解决方案