我创建了一个小函数和小触发器。当我运行最简单的DELETE
查询时,我只在控制台中看到通知和上下文消息(没有警告,也没有错误消息),但这个DELETE
查询仍然没有效果(记录保持在表并没有删除)。函数和触发器如下所示:
CREATE FUNCTION trigger_layers_before_del () RETURNS trigger
AS $$
DECLARE
table_name text := (SELECT concat ('layer_', OLD.id::text, '_'));
BEGIN
EXECUTE '
DROP TABLE IF EXISTS ' || quote_ident(table_name) || ' CASCADE
';
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER tr_layers_del_befor
BEFORE DELETE ON layers FOR EACH ROW
EXECUTE PROCEDURE trigger_layers_before_del();
这就是DELETE
命令的样子:
DELETE FROM layers where id = 31
所以,如果我跑:
DELETE FROM layers WHERE id = 31;
SELECT * FROM layers WHERE id = 31;
然后返回id = 31
的记录。
通知说," table" layer_31 _"不存在,跳过......"。上下文消息只打印EXECUTE
语句。那么,如果没有错误,为什么DELETE
命令没有被提交?
答案 0 :(得分:4)
这是因为你的函数返回NULL
。根据{{3}}:
每行触发器调用的触发器函数可以返回表行 (调用执行程序的值类型为HeapTuple),如果他们选择的话。一个 在操作具有以下选项之前触发的行级触发器:
它可以返回NULL以跳过当前行的操作。这指示执行程序不执行该行级操作 调用触发器(插入,修改或删除) 特别的表格行。)
仅适用于行级INSERT和UPDATE触发器,返回的行 成为将要插入的行或将替换正在行的行 更新。这允许触发器功能修改行 插入或更新。
不打算导致其中任何一个的行级BEFORE触发器 这些行为必须小心返回,因为它的结果是同一行 传入的(即INSERT和UPDATE的NEW行) 触发器,DELETE触发器的OLD行)。
所以,你需要的是RETURN OLD;