我是SQL编程的新手,但无法在线找到该问题的答案。
我正在使用pl / pgsql,希望获得以下结果:
我有一个具有某些属性的表A。我应该随时对该表进行更新- 因此,只要做出可能影响A值的更改(在与A相关的其他表B或C中),就会触发一个触发器来更新值(在此过程中- 可以将新值插入A,也可以删除旧值)。同时,我想防止有人将值插入A。
我想做的是创建一个触发器,该触发器将防止插入到A中(通过返回NULL)-但我 不 希望在从另一个触发器插入时调用此触发器-因此最终- 插入到A中只能在特定触发器内使用。
如前所述,我是SQL的新手,我不知道这样做是否可行。
是的,完全有可能。
UPDATE
A
我将特权运行:
REVOKE ALL ON TABLE A FROM public; -- and from anybody else who might have it
这就使得诸如postgres忽略这些低限制的超级用户。抓住那些你的触发功能上里面A有pg_has_role():
postgres
pg_has_role()
IF pg_has_role('postgres', 'member') THEN RETURN NULL; END IF;
postgres实际的超级用户在哪里。注意:这也捕获其他超级用户,因为它们是每个角色的成员,甚至其他超级用户也是如此。
您可以采用类似的方式(替代该REVOKE方法)来捕获非超级用户。
REVOKE
创建一个非登录角色,该角色可以更新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和C, 拥有 此守护进程的作用,并用SECURITY DEFINER。细节:
B
C
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。
ON UPDATE CASCADE