PostgreSQL 中视图的触发器

Ari*_*jas 5 sql postgresql triggers plpgsql sql-view

我想在 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();
Run Code Online (Sandbox Code Playgroud)

Erw*_*ter 5

  • 函数中的语句末尾缺少分号 ( ; )。INSERT

  • insert是SQL 标准中的保留字,不应用作触发器或函数名称。即使 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 ?? = ??;
Run Code Online (Sandbox Code Playgroud)

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

  • 并且始终将列定义列表添加到您的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;
Run Code Online (Sandbox Code Playgroud)

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