无法删除Postgresql

时间:2016-03-09 09:25:18

标签: 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();

这就是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命令没有被提交?

1 个答案:

答案 0 :(得分:4)

这是因为你的函数返回NULL。根据{{​​3}}:

  

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

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

  •   
  • 仅适用于行级INSERT和UPDATE触发器,返回的行   成为将要插入的行或将替换正在行的行   更新。这允许触发器功能修改行   插入或更新。

  •   
     

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

所以,你需要的是RETURN OLD;