我想知道是否从另一个触发器函数内部调用了插入/更新/删除操作,这样我就可以在表X上应用一个不允许插入/更新/删除操作的触发器,除非该操作是从表Y上的触发器功能。
换句话说,我希望在发出插入/更新/删除操作时在表Y上有一个触发器,检查是否从表X触发器调用了操作,如果是,则继续 - 否则,拒绝行动。
我还认为,触发器功能可用的“请求源”信息可能有助于调试,具体取决于触发器的层次结构。
答案 0 :(得分:2)
您在此提出的建议违背了启用或拒绝访问数据库中数据的标准方法。通常,您可以通过GRANT
对表和函数的权限来解决此问题。您的案例可以这样解决:
首先,创建具有特定角色(= user,group)的表,例如“admin”。
CREATE TABLE x (...);
ALTER TABLE x OWNER to admin; -- Not necessary if "admin" created the table
CREATE TABLE y (...);
ALTER TABLE y OWNER to admin;
此时只有角色“admin”可以访问这些表。如果您希望其他用户(例如,角色“app_user”)从表x
中进行选择并从表y
中选择,插入,更新和删除,那么您应该明确GRANT
这些权限:< / p>
GRANT SELECT ON x TO app_user;
GRANT SELECT, INSERT, UPDATE, DELETE ON y TO app_user;
然后在表y
上定义触发器,并在触发器功能中将更改级联到表x
;我想你已经解决了这个问题。这里的诀窍是让“admin”用户作为触发器函数的所有者(这是合乎逻辑的,因为只有“admin”可以CREATE TRIGGER
在表y
上),然后使用SECURITY DEFINER
。这意味着即使“app_user”执行调用触发器的INSERT INTO y ...
,也会使用用户“admin”的权限执行级联表x
上的操作的触发器函数:
CREATE FUNCTION my_trigger_func RETURNS trigger AS $$
BEGIN
-- Perform some operation on x
RETURN NEW; -- or OLD
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
ALTER FUNCTION my_trigger_func OWNER TO admin; -- If needed
REVOKE ALL ON FUNCTION my_trigger_func FROM public;
CREATE TRIGGER my_trigger
BEFORE INSERT, UPDATE, DELETE ON y -- or AFTER, depending on your needs
FOR EACH ROW EXECUTE PROCEDURE my_trigger_func();
请注意,触发器函数不需要GRANT EXECUTE
:因为“app_user”具有调用触发器运行触发器功能的表y
的权限,所以允许“app_user”执行触发功能。
遵循此过程,“app_user”可以修改表x
的唯一方法是通过表y
。使用“admin”可以直接修改表x
,但作为表和触发器所有者,此角色应该知道比直接修改表x
更好。