Postgres:在有条件地运行更新或删除之前检查值

发布于 2024-09-28 23:47:43 字数 556 浏览 0 评论 0原文

我有一个相当简单的表,它将记录的作者存储在文本字段中,如下所示:

CREATE TABLE "public"."test_tbl" (
  "index" SERIAL, 
  "testdate" DATE, 
  "pfr_author" TEXT DEFAULT "current_user"(), 
  CONSTRAINT "test_tbl_pkey" PRIMARY KEY("index");

用户将永远不会看到索引或 pfr_author 字段,但我希望他们能够更新 testdate 字段或删除整个字段记录(如果他们获得许可并且他们是作者)。即,如果 test_tbl.pfr_author = CURRENT_USER 那么允许更新或删除,但如果不允许,则引发错误消息,例如“抱歉,您无权编辑此记录。”。

我没有走上使用触发器的路线,因为我认为即使它在行更新之前执行,用户请求的更新仍然会在行更新之后发生。

我尝试通过规则执行此操作,但当我在规则中放置更新命令时,最终会出现无限递归。有没有办法单独使用规则或规则和触发器的组合来做到这一点?

非常感谢您的帮助!

I've got a fairly simple table which stores the records' authors in a text field as shown here:

CREATE TABLE "public"."test_tbl" (
  "index" SERIAL, 
  "testdate" DATE, 
  "pfr_author" TEXT DEFAULT "current_user"(), 
  CONSTRAINT "test_tbl_pkey" PRIMARY KEY("index");

The user will never see the index or pfr_author fields, but I'd like them to be able to UPDATE the testdate field or DELETE whole records if they have permission and if they are the author. i.e. if test_tbl.pfr_author = CURRENT_USER THEN permit the UPDATE OR DELETE, but if not then raise an error message such as "Sorry, you do not have permission to edit this record.".

I have not gone down the route of using a trigger as I figure that even if it is executed before row update the user-requested update will still take place afterwards regardless.

I've tried doing this through a rule, but end up with infinite recursion as I put an update command inside the rule. Is there some way to do this using rules alone or a combination of a rule and trigger?

Thanks very much for any help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

暮倦 2024-10-05 23:47:43

在 UPDATE 和 DELETE 上使用行级 BEFORE 触发器来执行此操作。当不允许该操作时,只需让它返回 NULL 即可跳过该操作。

http://www.postgresql.org/docs/9.0/interactive/trigger -definition.html

Use a row level BEFORE trigger on UPDATE and DELETE to do this. Just have it return NULL when the operation is not permitted and the operation will be skipped.

http://www.postgresql.org/docs/9.0/interactive/trigger-definition.html

惟欲睡 2024-10-05 23:47:43

触发函数有一些问题,导致递归循环更新。你应该这样做:

CREATE OR REPLACE FUNCTION "public"."test_tbl_trig_func" () RETURNS trigger AS $body$ 
BEGIN 
IF not (old.pfr_author = "current_user"() OR "current_user"() = 'postgres') THEN 
    NULL;  
END IF; 
RETURN new;
END; 
$body$ LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER COST 100; 

我有一个这样的测试,它做得很好;

UPDATE test_tbl SET testdate = CURRENT_DATE WHERE test_tbl."index" = 2; 

the trigger function have some problem,resulting recursive loop update.You should do like this:

CREATE OR REPLACE FUNCTION "public"."test_tbl_trig_func" () RETURNS trigger AS $body$ 
BEGIN 
IF not (old.pfr_author = "current_user"() OR "current_user"() = 'postgres') THEN 
    NULL;  
END IF; 
RETURN new;
END; 
$body$ LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER COST 100; 

I have a test like this,it does well;

UPDATE test_tbl SET testdate = CURRENT_DATE WHERE test_tbl."index" = 2; 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文