我想知道是否从另一个触发器函数内部调用了插入/更新/删除操作,以便我可以在表X上应用不允许插入/更新/删除操作的触发器,除非从触发器函数执行操作在桌子上Y.
换句话说,我希望在发出插入/更新/删除操作时在表Y上有一个触发器,检查是否从表X触发器调用了操作,如果是,则继续 – 否则,拒绝该操作.
我还认为,触发器功能可用的“请求源”信息可能有助于调试,具体取决于触发器的层次结构.
最佳答案 您在此提出的建议违背了启用或拒绝访问数据库中数据的标准方法.通常,您可以通过对表和函数的GRANTing权限来解决此问题.您的案例可以像这样解决:
首先,创建具有特定角色(= 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 SELECT ON x TO app_user;
GRANT SELECT, INSERT, UPDATE, DELETE ON y TO app_user;
然后,您可以在表y上定义触发器,并在触发器功能中将更改级联到表x;我想你已经解决了这个问题.这里的技巧是让“admin”用户作为触发器功能的所有者(这是合乎逻辑的,因为只有“admin”可以在表y上创建TRIGGER然后使用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更好.