确定触发器函数内的更新是否导致另一个触发器被触发

5
我想知道是否从另一个触发器函数内调用了插入/更新/删除操作,以便我可以在表X上应用一个触发器,该触发器不允许插入/更新/删除操作,除非该操作是从表Y上的触发器函数执行的。
换句话说,在表Y上有一个触发器,当发出插入/更新/删除操作时,检查该操作是否是从表X触发器调用的,如果是,则继续执行 - 否则,拒绝该操作。
我还认为,将“请求来源”信息提供给触发器函数可能有助于调试,具体取决于触发器层次结构。
1个回答

3

你在这里提出的方案违反了启用或拒绝数据库中数据访问的标准方式。通常,您可以通过在表和函数上授予权限来解决此问题。您的情况可以通过以下方式解决:

首先,使用特定角色(用户、组)创建表,例如“管理员”。

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;

目前只有“管理员”角色可以访问表格。如果您希望其他用户 (比如"app_user"角色) 可以从表 x 中进行选择,并且可以从表 y 进行选择、插入、更新和删除操作,那么您需要明确地授予权限:GRANT

GRANT SELECT ON x TO app_user;
GRANT SELECT, INSERT, UPDATE, DELETE ON y TO app_user;

您需要在表y上定义一个触发器,并在触发器函数中将更改级联到表x;我假设您已经解决了这个问题。这里的诀窍是将“admin”用户作为触发器函数的所有者(因为只有“admin”可以在表y上创建触发器),然后使用SECURITY DEFINER。这意味着即使“app_user”执行了一个INSERT INTO y ...,触发器被调用,级联操作表x的触发器函数也会以用户“admin”的权限执行:
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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接