如何防止批量行删除操作?

时间:2018-09-07 01:44:15

标签: postgresql triggers delete-row

我完全可以这样防止DELETE:

CREATE TRIGGER prevent_multiple_row_del
BEFORE DELETE ON ALL
BEGIN
RAISE EXCEPTION 'Cant delete more than 1 row at a time';
END;

但是如何检查删除操作是否会导致删除多行?删除不是问题,只要它被限制为一个常数(1或5或10,只要它不是无限的即可)即可。

或者,如何允许删除但禁止删除整个表?

1 个答案:

答案 0 :(得分:2)

之前语句触发器太早了,无法知道受影响的行。

对于全表删除,请使用 after语句触发器。您所需要做的就是从表格中选择并查看其中是否还有记录。

对于最多删除n条记录,这也必须在声明后确定。您标记了问题PostgreSQL,但是因为a_horse_with_no_name指出您的代码是Oracle。在PostgreSQL中,您要检查pg_affected_rows(),在Oracle SQL%ROWCOUNT中。我不知道PostgreSQL是否允许在after语句触发器中检查pg_affected_rows()。对于Oracle,在after语句触发器中检查SQL%ROWCOUNT无效。现在检查该变量为时尚早。

因此至少对于Oracle来说,诀窍是要有一些自定义计数器,以将在语句前设置为零,在每行后增加 ,然后在语句后检查 。我不确切地知道如何在PostgreSQL中做到这一点,但是肯定会有一种方法。在Oracle中,您将使用复合触发器,即包含单个触发器的超级触发器。

CREATE OR REPLACE TRIGGER prevent_multiple_row_del
FOR DELETE ON mytable COMPOUND TRIGGER
  v_count INTEGER := 0;

  AFTER EACH ROW IS
  BEGIN
    v_count := v_count + 1;
  END AFTER EACH ROW;

  AFTER STATEMENT IS
  BEGIN
    IF v_count > 1 THEN
      raise_application_error(-20000, 'Can''t delete more than 1 row at a time');
    END IF;
  END AFTER STATEMENT;

END prevent_multiple_row_del;