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)
函数中的语句末尾缺少分号 ( ; )。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的是。