Postgresql

觸發器不在分區表上執行

  • March 6, 2012

我正在使用 PostgreSQL。我有一個表,我已將其劃分為三個子表 - 據我所知,這一切都正常工作。行被正確插入到適當的分區中並且主表保持為空。

我的問題是主表上的觸發器之一不再在插入或更新時執行。其他觸發器正常執行,並且此觸發器在分區之前正常工作。

我懷疑這可能類似於約束和索引,並且需要將觸發器應用於子表,但這也不起作用。

其他觸發器工作,如果它們按照文件建議按字母順序執行,則所有觸發器都應在分區查找觸發器之前執行。

讓我傷心的觸發因素:

CREATE FUNCTION set_expiry_timestamp() RETURNS trigger AS $BODY$
BEGIN
   -- Don't re-generate if the timeleft value has not changed
   IF (TG_OP = 'UPDATE') THEN
       IF OLD.expires IS NOT NULL AND OLD.timeleft = NEW.timeleft THEN
           RETURN NEW;
       END IF;
   END IF;

   IF (NEW.timeleft = 'SHORT') THEN
       NEW.expires := NEW.updated + interval '30 minutes';
   ELSIF (NEW.timeleft = 'MEDIUM') THEN
       NEW.expires := NEW.updated + interval '2 hours';
   ELSIF (NEW.timeleft = 'LONG') THEN
       NEW.expires := NEW.updated + interval '12 hours';
   ELSIF (NEW.timeleft = 'VERY_LONG') THEN
       NEW.expires := NEW.updated + interval '48 hours';
   ELSE
       RAISE EXCEPTION 'timeleft was unrecognised. Expected SHORT, MEDIUM, LONG or VERY_LONG.';
   END IF;
   RETURN NULL;
END;
$BODY$
LANGUAGE plpgsql;

CREATE TRIGGER set_expiry AFTER INSERT OR UPDATE ON auction FOR EACH ROW EXECUTE PROCEDURE set_expiry_timestamp()

預期執行觸發器的查詢:

INSERT INTO auction (created, timeleft) VALUES (NOW(), 'SHORT');

updatedBEFORE INSERT/UPDATE觸發器中設置,但是在提供更新時它仍然不會觸發。

有什麼建議?

觸發器是在插入或更新**之後。**正如您在函式中看到的那樣,它以:

RETURN NULL;

這意味著該行將被丟棄,對該行的任何更改都是無效的。實際上,從AFTER觸發器返回的行在任何情況下都會被丟棄。這RETURN NULL只是一個提醒。

您需要在BEFORE觸發器中執行此操作或發出顯式UPDATE語句。然而,第二個選項非常棘手,因為您最終可能會陷入無限循環。最好讓它成為BEFORE觸發器。


順便說一句:條件表達式可以用一個CASE語句來簡化(從 8.4 版開始):

CASE NEW.timeleft
WHEN 'SHORT' THEN
   NEW.expires := NEW.updated + interval '30 minutes';
WHEN 'MEDIUM' THEN
   NEW.expires := NEW.updated + interval '2 hours';
...
ELSE
   RAISE EXCEPTION 'timeleft was unrecognised. ...';
END CASE;

引用自:https://dba.stackexchange.com/questions/14515