sql - 仅允许从触发器内插入

标签 sql postgresql triggers insert plpgsql

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

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

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

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

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

最佳答案

是的,完全有可能。

1。通常不允许 UPDATEA

我会以特权进行操作:

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

这使得诸如 postgres 之类的 super 用户忽略了这些低级限制。使用 pg_has_role()A 上捕获触发函数内的内容:

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

其中 postgres 是实际的 super 用户。注意:这也会捕获其他 super 用户,因为他们是每个角色的成员,甚至是其他 super 用户。

您可以以类似的方式捕获非 super 用户(替代 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 .

关于sql - 仅允许从触发器内插入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20151331/

相关文章:

javascript - 如何修复 NPM 安装 SQLite 构建失败?

mysql - 如果我不想显示前 10 条记录列表,我可以使用什么

sql - 恢复数据库 — 错误 RESTORE HEADERONLY 异常终止。

MySQL 触发器问题

mysql - 条件窗函数

postgresql - 如何获取 Postgresql 程序警告信息?

java - 如何使用 PreparedStatement 和 Case INsensitive 搜索

python - 我可以更改模型字段的类型吗?

sql - 无效的新或旧规范错误

mysql - 使用触发器计算金额..但无法获取价格值