PostgreSQL中的TRIGGER ON VIEW不会触发

时间:2019-04-03 08:18:37

标签: sql postgresql triggers sql-view

我正在尝试在PostgreSQL 9.6的VIEW上添加触发器。

这是我的观点:

CREATE VIEW names AS
SELECT one.name AS name_one, two.name AS name_two, three.name AS name_three
FROM table_one one
LEFT JOIN table_two two ON one.id = two.id
LEFT JOIN table_three three ON two.id = three.id;

这是我的触发功能:

CREATE OR REPLACE FUNCTION notify_name_changed() RETURNS trigger AS $BODY$
  BEGIN
    PERFORM pg_notify('name_changed', row_to_json(NEW)::text);
    RETURN NULL;
  END; 
$BODY$ LANGUAGE plpgsql;

还有我的CREATE TRIGGER

CREATE TRIGGER notify_name_changed INSTEAD OF INSERT OR UPDATE OR DELETE ON "names"
  FOR EACH ROW EXECUTE PROCEDURE notify_name_changed();

只要其中一个基表中发生任何事情,这都不会触发任何更改。 但是,创建3个单独的触发器确实可以,但是与视图无关:

CREATE TRIGGER notify_name_changed AFTER INSERT OR UPDATE OR DELETE ON "one"
  FOR EACH ROW EXECUTE PROCEDURE notify_name_changed();

CREATE TRIGGER notify_name_changed AFTER INSERT OR UPDATE OR DELETE ON "two"
  FOR EACH ROW EXECUTE PROCEDURE notify_name_changed();

CREATE TRIGGER notify_name_changed AFTER INSERT OR UPDATE OR DELETE ON "three"
  FOR EACH ROW EXECUTE PROCEDURE notify_name_changed();

是否可以直接在视图上添加触发器,如果​​该视图中使用的基表发生任何更改,则该触发器会触发?

1 个答案:

答案 0 :(得分:1)

我认为您误解了视图的概念。

视图不包含任何数据,您可以将其视为具有名称的“明确的SQL语句”。每当在查询中使用视图时,在“查询重写”步骤中将其替换为其定义。

仅当您更新视图本身而不是基础表时,才会触发视图上fetch=FetchType.EAGER的{​​{1}}触发器。为此,您必须在这些表上定义触发器。

您可能缺少的一点是,如果基础表中发生某些更改,则视图中的内容会立即更改,因为该视图只是对基表的查询。