【问题标题】:Allow insertion only from within a trigger只允许从触发器内插入
【发布时间】:2013-11-22 17:50:48
【问题描述】:

我是 SQL 编程新手,在网上找不到这个问题的答案。

我正在使用 pl/pgsql,我希望获得以下结果:

我有一个具有某些属性的表 A。 我应该随时更新此表 - 因此,每当进行可能影响 A 值的更改(在与 A 相关的其他表 B 或 C 中)时 - 触发更新值的触发器(在此过程中 -可以将新值插入 A,也可以删除旧值)。 同时,我想防止有人在 A 中插入值。

我想要做的是创建一个触发器来防止插入 A(通过返回 NULL) - 但我希望在我进行插入时调用此触发器从另一个触发器 - 所以最终 - 只允许从特定触发器内插入 A。

正如我之前所说,我是 SQL 新手,我什至不知道这是否可能。

【问题讨论】:

    标签: sql postgresql triggers insert plpgsql


    【解决方案1】:

    是的,完全有可能。

    1。一般不允许 UPDATEA

    我会以特权操作:

    REVOKE ALL ON TABLE A FROM public;  -- and from anybody else who might have it
    

    这使得像postgres 这样的超级用户忽略了这些低级限制。在A 上用pg_has_role() 捕获您的触发函数中的那些:

    IF pg_has_role('postgres', 'member') THEN
       RETURN NULL;
    END IF;
    

    postgres 是真正的超级用户。注意:这也会捕获其他超级用户,因为他们是每个角色的成员,甚至是其他超级用户。

    您可以以类似的方式捕获非超级用户(替代REVOKE 方法)。

    2。允许 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;
    

    在表BC 上创建触发器函数,拥有 由该守护进程角色和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

    【讨论】:

      猜你喜欢
      • 2021-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多