【问题标题】:Triggers on Views in PostgreSQLPostgreSQL 中视图的触发器
【发布时间】:2012-12-20 13:43:08
【问题描述】:

我想在 PostgreSQL 中为我的视图创建一个触发器。这个想法是所有新数据都必须满足要插入的条件。但是这里出了点问题,我在手册中找不到答案。

CREATE OR REPLACE VIEW My_View AS 
SELECT name, adress, count FROM club, band, country;

CREATE OR REPLACE FUNCTION insert() RETURNS TRIGGER AS $$
BEGIN
    IF(NEW.count > 10) THEN
    INSERT INTO My_View VALUES (NEW.name, NEW.adress, NEW.count);
    END IF;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER insert INSTEAD OF INSERT ON My_View
FOR EACH ROW EXECUTE PROCEDURE insert();

【问题讨论】:

  • 你的 postgresql 版本是多少?你有什么错误信息?你能在sqlfiddle.com 上打开一个沙盒吗?
  • 我的版本是 9.1 并且错误很奇怪,因为它看起来几乎永远不会结束循环......消息是“堆栈溢出”。错误在于“INSERT”
  • 也许你不应该称之为插入?

标签: sql postgresql triggers plpgsql sql-view


【解决方案1】:
  • 函数中INSERT 语句的末尾缺少分号 (;)。

  • insert 是 SQL 标准中的 reserved word,不应用作触发器或函数名称。即使它在 PostgreSQL 中被允许,这也是一个非常个坏主意。

  • 您的视图定义中没有三个表club, band, country 的连接条件。这导致CROSS JOIN,它可能非常昂贵。如果每个表中有 1000 行,您将获得 1,000,000,000 个组合。你绝对不希望这样。

  • 此外,您应该对视图定义中的列进行表格限定以避免歧义。

CREATE OR REPLACE VIEW my_view AS 
SELECT ??.name, ??.address, ??.mycount
FROM club    cl
JOIN band    ba ON ?? = ??
JOIN country co ON ?? = ??;

你需要填写我留下问号的地方。

  • 并且始终将列定义列表添加到您的 INSERT 语句中。

  • 最后,您确实不想再次将INSERT 放入同一个视图中,这会造成无限循环,并且可能是导致错误的主要原因。

CREATE OR REPLACE FUNCTION f_insert()
  RETURNS TRIGGER AS
$func$
BEGIN
   IF NEW.mycount > 10 THEN
      INSERT INTO my_view ???? (col1?, col2?, col3?)
      VALUES (NEW.name, NEW.address, NEW.mycount);
   END IF;
END
$func$ LANGUAGE plpgsql;

顺便说一句,您也不应该使用count 作为标识符。我改用mycount

【讨论】:

  • 好的,我明白了,那我应该怎么写那个条件呢?
  • @Noran: 如果表band 有一个列country_id 引用表countrycountry_id,你写:JOIN country co ON co.country_id = ba.country_id 等等。你真的需要先了解这些基础知识你甚至可以开始在视图上使用INSTEAD 触发器。
  • 是的,我知道这一点,我明白这一点。我在想那个插入。因为方式: INSERT INTO col1, col2, col3 VALUES NEW.col1, NEW.col2, NEW.col3 不起作用。我在那里遇到语法错误。
  • 嗯……我完了,我的大脑已经煮熟了。我明天会看看这个。感谢您的耐心和帮助。
  • @Noran 您正在通过让视图上的触发器尝试插入视图来创建无限循环。您的DO INSTEAD 触发器必须插入到视图SELECTs 其数据来自的基础表中。在这种情况下,您将插入bandcountry 和/或club
猜你喜欢
  • 2014-08-11
  • 2015-09-21
  • 2011-03-15
  • 1970-01-01
  • 2014-10-01
  • 2016-08-22
  • 1970-01-01
相关资源
最近更新 更多