CREATE TABLE lab7.standings
(
team_name VARCHAR(100) NOT NULL PRIMARY KEY,
wins INTEGER,
losses INTEGER,
winPct NUMERIC,
CHECK(wins > 0),
CHECK(losses >0)
);
CREATE OR REPLACE FUNCTION
calc_winning_percentage()
RETURNS trigger AS $$
BEGIN
New.winPct := New.wins /(New.wins + New.losses);
RETURN NEW;
END;
$$LANGUAGE plpgsql;
CREATE TRIGGER
update_winning_percentage
AFTER INSERT OR UPDATE ON standings
FOR EACH ROW EXECUTE PROCEDURE calc_winning_percentage();
这准确地更新了我的排名表中的胜利,但似乎没有发送我新计算的胜率。
答案 0 :(得分:2)
试试这个:
CREATE TRIGGER update_winning_percentage
BEFORE INSERT OR UPDATE ON standings
FOR EACH ROW EXECUTE PROCEDURE calc_winning_percentage();
答案 1 :(得分:2)
除了将触发器更改为BEFORE
之外的integer
:
我注意到表定义中的三个事物:
numeric
与wins
losses
和winPct
的类型为pointed out by @Grijesh,但SELECT 1 / 4, 2 / 4
为integer
。
尝试以下方法:
0
两次都给你integer
。结果类型为integer
,小数位截断为零。在 numeric
结果被强制转换为wins
之前,您的触发器函数会发生这种情况。因此,losses
和numeric
中仅影响小数位的更改会丢失到结果中。修复此问题:
..将基本表格中所有相关列的列定义更改为NEW.winPct := NEW.wins::numeric / (NEW.wins + NEW.losses);
。
..或更改触发功能:
numeric
将计算中的一个数字投射到::numeric
(numeric
)会强制结果为integer
并保留小数位数。
我强烈建议 第二个变体,因为wins
显然是losses
和NEW.winPct := NEW.wins::float8 / (NEW.wins + NEW.losses);
的正确类型。如果您的百分比不必非常精确,我还会考虑使用普通numeric
作为百分比。然后您的触发器可以使用:
winPct
winpct
它被转换为小写,实际上只是lab7.standings
。请务必阅读floating point type (real
or double precision
)。
您的表格显然属于非标准架构:search_path
。除非...
BEFORE INSERT OR UPDATE ON lab7.standings
...
中包含该内容,否则触发器创建必须使用模式限定名称:
{{1}}
显示使用此类问题发布表定义的重要性。