在PostgreSQL中禁用表上的DELETE?

mik*_*iku 19 postgresql audit triggers plpgsql sql-delete

对于安全性敏感的设计,我想禁用DELETEs某些表.

所述DELETE应该仅设置一个deleted上的行(这将是然后在视图,这将被本应用层可以使用可见)标志.

据我所知,规则会生成其他查询 - 因此规则无法抑制原始查询.

举例说明带触发器的玩具示例(尚未测试):

-- data in this table should be 'undeletable'
CREATE table article (
    id serial,
    content text not null,
    deleted boolean default false
)

-- some view that would only show articles, that are NOT deleted
...

-- toy trigger (not tested)
CREATE OR REPLACE FUNCTION suppress_article_delete()
RETURNS TRIGGER AS $sad$
BEGIN
    IF (TG_OP = 'DELETE') THEN
        UPDATE article SELECT id, content, TRUE;
        -- NEW or NULL??
        RETURN NEW;
    END IF;
    RETURN NULL;
END;
$sad$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

抑制一个什么是好方法DELETE

Mil*_*dev 25

据我所知,规则会生成其他查询 - 因此规则无法抑制原始查询.

不是 - 它可能是一个INSTEAD规则:

 CREATE RULE shoe_del_protect AS ON DELETE TO shoe DO INSTEAD NOTHING;
Run Code Online (Sandbox Code Playgroud)

(手册同一页上的一个例子).

另一种方法是REVOKE删除有问题的表上的权限,并创建用于删除...的存储过程,也可能更新和插入.

  • ON DELETE DO INSTEAD NOTHING 的问题是发出 DELETE 的代码不会收到没有发生任何事情的通知 - DELETE 对于客户端来说将会成功,并且可能会发生静默错误。 (4认同)
  • @peschü 是的。避免该问题的一种方法是:`create or Replace function raiseException() returns void language plpgsql volatile as $$ begin raise exception 'Cannot delete row.'; 结束$$; 创建或替换规则 Prevent_deletes AS ON DELETE TO ShoDO INSTEAD select raiseException(); ` (3认同)