我是SQL编程的新手,我无法在线找到这个问题的答案。
我正在使用pl / pgsql,我希望得到以下结果:
我有一张具有某些属性的表A. 我应该随时更新此表 - 因此每当做出可能影响A值的更改时(在与A相关的其他表B或C中) - 会触发一个更新值的触发器(在此过程中 - 可以将新值插入A中,也可以删除旧值)。 同时,我想阻止某人将值插入A。
我想要做的是创建一个阻止插入A(通过返回NULL)的触发器 - 但我不希望在我插入时调用此触发器来自另一个触发器 - 所以最终 - 只允许从特定触发器中插入A。
正如我之前所说,我是SQL的新手,我不知道这是否可行。
答案 0 :(得分:1)
是的,完全有可能。
UPDATE
到A
我会使用特权进行操作:
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
方法)。
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
在表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依赖关系,您还可以使用foreign key constraints (additionally) using ON UPDATE CASCADE
。