2016-02-27 84 views
1

我開始對術語有點困惑,我開始相信我所希望實現的是不可能的。是否有可能創建一個觸發器,當視圖內的信息發生變化時觸發,而不是通過視圖本身的UPDATE/INSERT/DELETE聲明,而是視圖組成的表之一。間接更新視圖內容時觸發不會觸發

如果沒有,是否有一種有效的方法來過濾哪些查詢會觸發一個觸發器?

爲了給出更多的上下文,我有一個用戶表和一個位置表。我只關心每個用戶在特定區域內的最新位置。我創建了一個觀點如下:

CREATE OR REPLACE VIEW "users_near_coordinate" AS 
SELECT DISTINCT ON ("User"."id") "User"."id", "User"."displayName", "UserLocation"."location", "UserLocation"."createdAt" 
FROM "User", "UserLocation" 
WHERE "UserLocation"."userId" = "User"."id" AND ST_Distance_Sphere(location, ST_MakePoint(long,lat)) <= 5 * 1609.34 
ORDER BY "User"."id", "UserLocation"."createdAt" DESC; 

然後我有一個觸發器,具體如下:

CREATE OR REPLACE FUNCTION notify_user_moved_within_range() RETURNS trigger AS $$ 
DECLARE 
BEGIN 
    PERFORM pg_notify('user_nearby_inserted', TG_TABLE_NAME || ':' || NEW); 
    RETURN new; 
END; 
$$ LANGUAGE plpgsql; 

CREATE TRIGGER "user_moved_within_range" INSTEAD OF INSERT ON "users_near_coordinate" FOR EACH ROW EXECUTE PROCEDURE notify_user_moved_within_range(); 

我也用AFTER INSERT [...] FOR EACH STATEMENT組合試過,但觸發不以往任何時候都似乎被辭退了。

爲了測試,我插入的位置:

INSERT INTO "public"."UserLocation"("userId", "scenarioId", "location", "createdAt", "updatedAt") VALUES('8041849f-a204-4511-b6fa-74f3b731fd1f', '1', ST_GeomFromText('POINT(long lat)', 4326), now(), now()); 

回答

1

次數比SQL宏的更多一點。它們實際上並不包含任何數據,並且在更新基礎表時,視圖中的任何內容都不會改變。因此,視圖上沒有INSERT事件可能觸發觸發器;你需要把你的觸發器放在桌子上。

通過將WHEN (<condition>) clause附加到CREATE TRIGGER語句中,您可以輕鬆定義觸發條件觸發條件。或者,您可以將條件邏輯置於觸發器功能本身,即:

IF <condition> THEN 
    PERFORM pg_notify(...); 
END IF; 
+0

這似乎是我正在尋找的解決方案。一旦我有一個粗糙的版本工作,我會給它一個鏡頭並標記爲正確的。你可以建議將條件添加到CREATE TRIGGER語句與函數內嗎?理論上,我的解決方案應該能夠擴展到非常多的觸發器 –