admin

只允许从触发器内插入

sql

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

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

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

我想做的是创建一个触发器,该触发器将防止插入到A中(通过返回NULL)-但我 希望在从另一个触发器插入时调用此触发器-因此最终-
插入到A中只能在特定触发器内使用。

如前所述,我是SQL的新手,我不知道这样做是否可行。


阅读 118

收藏
2021-06-07

共1个答案

admin

是的,完全有可能。

1.一般不允许UPDATEA

我将特权运行:

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

这就使得诸如postgres忽略这些低限制的超级用户。抓住那些你的触发功能上里面Apg_has_role()

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;

表上创建触发器的功能BC拥有 此守护进程的作用,并用SECURITY 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依赖关系,您还可以使用来处理外键约束(附加)ON UPDATE CASCADE

2021-06-07