仅允许从触发器内插入

时间:2013-11-22 17:50:49

标签: sql postgresql triggers insert plpgsql

我是SQL编程的新手,我无法在线找到这个问题的答案。

我正在使用pl / pgsql,我希望得到以下结果:

我有一张具有某些属性的表A. 我应该随时更新此表 - 因此每当做出可能影响A值的更改时(在与A相关的其他表B或C中) - 会触发一个更新值的触发器(在此过程中 - 可以将新值插入A中,也可以删除旧值)。 同时,我想阻止某人将值插入A。

我想要做的是创建一个阻止插入A(通过返回NULL)的触发器 - 但我希望在我插入时调用此触发器来自另一个触发器 - 所以最终 - 只允许从特定触发器中插入A。

正如我之前所说,我是SQL的新手,我不知道这是否可行。

1 个答案:

答案 0 :(得分:1)

是的,完全有可能。

1。通常不允许UPDATEA

我会使用特权进行操作:

REVOKE ALL ON TABLE A FROM public;  -- and from anybody else who might have it

这使postgres等超级用户忽略了这些低限制。使用pg_has_role()

A上的触发器功能中捕获这些内容
IF pg_has_role('postgres', 'member') THEN
   RETURN NULL;
END IF;

postgres是实际的超级用户。注意:这也吸引了其他超级用户,因为他们是每个角色的成员,甚至是其他超级用户。

您可以以类似的方式捕获非超级用户(替代REVOKE方法)。

2。允许UPDATE守护进程角色

创建一个非登录角色,允许更新A

CREATE ROLE a_update NOLOGIN;
-- GRANT USAGE ON SCHEMA xyz TO a_update;  -- may be needed, too
GRANT UPDATE ON TABLE A TO a_update;

通过此守护程序角色和B在表CSECURITY DEFINER拥有上创建触发器函数。详情:

添加到A上的触发器功能:

IF pg_has_role('postgres', 'member') THEN
   RETURN NULL;
ELSIF pg_has_role('a_update', 'member') THEN
   RETURN NEW;
END IF;

对于简单的1:1依赖关系,您还可以使用foreign key constraints (additionally) using ON UPDATE CASCADE