无法在 Postgresql 中删除一行

Jac*_*ian 3 postgresql

我创建了一个小功能和小触发器。当我运行最简单的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不提交命令?

Ego*_*gov 8

这是因为您的函数返回NULL. 根据文档

由每行触发器调用的触发器函数可以将表行(HeapTuple 类型的值)返回给调用执行程序(如果他们选择)。在操作之前触发的行级触发器有以下选择:

  • 它可以返回 NULL 以跳过当前行的操作。这指示执行程序不要执行调用触发器的行级操作(插入、修改或删除特定表行)。

  • 仅对于行级 INSERT 和 UPDATE 触发器,返回的行将成为将被插入或将替换正在更新的行的行。这允许触发器函数修改被插入或更新的行。

不打算导致这些行为中的任何一个的行级 BEFORE 触发器必须小心地将传入的同一行作为其结果返回(即,INSERT 和 UPDATE 触发器的 NEW 行,DELETE 触发器的 OLD 行)。

所以,你需要的是 RETURN OLD;