我创建了一个小功能和小触发器。当我运行最简单的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();
Run Code Online (Sandbox Code Playgroud)
这是DELETE命令的样子:
DELETE FROM layers where id = 31
Run Code Online (Sandbox Code Playgroud)
所以,如果我运行:
DELETE FROM layers WHERE id = 31;
SELECT * FROM layers WHERE id = 31;
Run Code Online (Sandbox Code Playgroud)
然后它返回一个记录id = 31。
通知说,“表“layer_31_”不存在,跳过......”。上下文消息只是打印EXECUTE语句。那么,如果没有错误,为什么DELETE不提交命令?
这是因为您的函数返回NULL. 根据文档:
由每行触发器调用的触发器函数可以将表行(HeapTuple 类型的值)返回给调用执行程序(如果他们选择)。在操作之前触发的行级触发器有以下选择:
它可以返回 NULL 以跳过当前行的操作。这指示执行程序不要执行调用触发器的行级操作(插入、修改或删除特定表行)。
仅对于行级 INSERT 和 UPDATE 触发器,返回的行将成为将被插入或将替换正在更新的行的行。这允许触发器函数修改被插入或更新的行。
不打算导致这些行为中的任何一个的行级 BEFORE 触发器必须小心地将传入的同一行作为其结果返回(即,INSERT 和 UPDATE 触发器的 NEW 行,DELETE 触发器的 OLD 行)。
所以,你需要的是 RETURN OLD;
| 归档时间: |
|
| 查看次数: |
4497 次 |
| 最近记录: |