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

时间:2010-10-26 15:43:22

标签: sql postgresql

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

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 THEN允许更新或删除,但如果没有,则提出错误消息,例如“抱歉,您无权编辑此记录。”。

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

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

非常感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

在UPDATE和DELETE上使用行级BEFORE触发器来执行此操作。只是在不允许操作时返回NULL,并跳过操作。

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

答案 1 :(得分:0)

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

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;