为什么在PostgreSQL中用于触发器的条件永远不满足?

v64noz0r  于 2023-06-22  发布在  PostgreSQL
关注(0)|答案(2)|浏览(146)

我试图创建简单的触发器,以确保“from”或“to”(数据库用户名)等于current_user,然后可以删除记录。但它总是提出一个例外。
表格架构:

CREATE TABLE policy_test (
 id serial not null,
 val varchar not null,
 "from" varchar not null,
 "to" varchar not null
)

我给予所有数据库用户选择,插入,更新,删除表policy_test。我确保“from”和“to”列始终是数据库用户名。
我创建了一个触发函数:

CREATE OR REPLACE FUNCTION can_delete_policy_test()
  RETURNS TRIGGER AS $func$
BEGIN
  IF NEW."from" = current_user::varchar OR 
  NEW."to" = current_user::varchar THEN
    RETURN NEW;
  ELSE 
    RAISE EXCEPTION 'You have no permission to delete this record.';
  END IF;
END;
$func$ LANGUAGE plpgsql;

我这样做是为了在'policy_test'表上使用触发器:

CREATE TRIGGER policy_test_delete_trigger
BEFORE DELETE ON policy_test
FOR EACH ROW 
EXECUTE FUNCTION can_delete_policy_test();

在调用语句之前,我确保了policy_test表上的某个记录中连接的数据库用户名。
然后我调用这个语句来删除记录:

DELETE FROM policy_test
WHERE "from" = current_user
OR "to" = current_user;
w8f9ii69

w8f9ii691#

问题是您正在使用NEWNEWDELETE触发器中为NULL,从触发器函数返回NULL将中止操作。你必须看看OLD."from"OLD."to"RETURN OLD;

3df52oht

3df52oht2#

我用RLS和策略来实现我想要的东西。

ALTER TABLE policy_test ENABLE ROW LEVEL SECURITY;

GRANT SELECT, DELETE ON TABLE policy_test TO "employee";

CREATE POLICY select_policy_test ON policy_test
FOR SELECT USING ( "to" = current_user::varchar );

CREATE POLICY delete_policy_test ON policy_test
FOR DELETE USING (
  "from" = current_user::varchar OR
  "to" = current_user::varchar    
);

相关问题