我完全可以这样防止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,只要它不是无限的即可)即可。
或者,如何允许删除但禁止删除整个表?
答案 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;