提问人:Zübeyir 提问时间:6/22/2023 更新时间:6/22/2023 访问量:33
为什么用于触发器的条件在 PostgreSQL 上从未满足?
Why is the condition used for the trigger never satisfied on PostgreSQL?
问:
我正在尝试创建简单的触发器以确保“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;
答:
2赞
Laurenz Albe
6/22/2023
#1
问题是您正在使用 . 在触发器中为 NULL,并且从触发器函数返回 NULL 将中止操作。你必须看 和 和 .NEW
NEW
DELETE
OLD."from"
OLD."to"
RETURN OLD;
0赞
Zübeyir
6/22/2023
#2
我使用 RLS 和 POLICY 来存档我想要的相同内容。
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
);
评论
NEW
OLD
NEW
NULL
DELETE