4

我想知道是否从另一个触发器函数内部调用了插入/更新/删除操作,以便我可以在不允许插入/更新/删除操作的表 X 上应用触发器,除非该操作是从触发器函数执行的在 Y 表上。

换句话说,我希望在发出插入/更新/删除操作时在表 Y 上有一个触发器,检查是否从表 X 触发器调用了该操作,如果是,则继续 - 否则,拒绝该操作。

我还相信,根据触发器的层次结构,让触发器功能可用的“请求源”信息可能有助于调试。

4

1 回答 1

2

您在这里提出的建议违背了启用或拒绝访问数据库中数据的标准方式。通常,您可以通过GRANT对表和函数设置权限来解决此问题。你的情况可以这样解决:

首先,创建具有特定角色(= 用户、组)的表,例如“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获得这些权限:

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

然后在 table 上定义一个触发器,y并在 trigger 函数中将更改级联到 table x;我假设你已经解决了这个问题。这里的技巧是让“admin”用户作为触发器函数的所有者(这是合乎逻辑的,因为只有“admin”可以CREATE TRIGGER在 table 上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是通过 table y。使用“admin”可以直接修改表x,但是作为表和触发器所有者,这个角色应该比直接修改表更清楚x

于 2015-05-10T03:25:17.153 回答