sql - 如何比较 postgres 更新策略中一行的旧值和新值

标签 sql postgresql row-level-security

我有一个权限结构,因此特定权限只允许编辑我表中 5 个字段中的 2 个。我的整个系统中都有 RLS,因此我需要在策略中执行上述内容。

起初我想写一个函数来检查用户是否更新了他们没有权限更新的字段,并在策略中使用它的返回值。但是我无法找到一种无需定义变量就可以在策略中使用返回值的方法,显然你不能在策略中定义变量。

这是上述功能:

CREATE OR REPLACE FUNCTION is_user_updating_non_permitted_fields(id uuid, fieldA integer, fieldB text...)
.....
 DECLARE
  old_row MY_TABLE
 BEGIN
  SELECT * FROM MY_TABLE m WHERE id = m.id INTO old_row;
  IF (fieldA != old_row.fieldA OR fieldB != old_row.fieldB)
    THEN RETURN 1;
    ELSE RETURN 0;
  ENDIF;
 END;
....

政策将是这样的:

CREATE POLICY my_table_update ON MY_TABLE FOR UPDATE
WITH CHECK (
 (SELECT CASE WHEN (
    ''use function here''
   ) = 1 THEN false ELSE true END;
 )
)

作为最后的手段,我考虑过在更新前触发并使用 ROLLBACK TRANSACTION 但我真的不想那样做。

最佳答案

根据 the documentation ,那是不可能的:

Only rows for which the expression evaluates to true will be allowed. An error will be thrown if the expression evaluates to false or null for any of the records inserted or any of the records that result from the update. Note that the check_expression is evaluated against the proposed new contents of the row, not the original contents.

毕竟你将不得不使用触发器。

关于sql - 如何比较 postgres 更新策略中一行的旧值和新值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66747654/

相关文章:

sql - 在 Where 子句中使用 Case 语句(带专栏)

mysql - 将现有表数据从只读数据库复制到读写数据库MySQL

javascript - 如何在 postgres plv8 过程中记录字符串?

mysql - 通过rails session 参数过滤MySQL数据

query-performance - 行级安全性,性能差

PostgreSQL 9.5 - 行级安全性/ROLE 最佳实践

MySQL 查询 10 个表(Sequelize 或 Raw Query)

mysql - 前日SQL成交量

node.js - 如何在 Sequelize.js 中创建一个端点来接收模型中的任何随机 JSON?

postgresql - 将 Docker PostgreSQL 数据存储到 Azure 存储帐户