我有两个返回好价值的函数。但是当我在触发器中调用这些函数时,它们总是返回0而不是良好的值。
这些函数的返回类型是real
。直接和戏剧性的结果是触发器在调用时会在表中插入错误的值。
功能:
create or replace function get_remaining_hour(id_user_v integer,id_absence_v_type integer,id_year_v integer) returns real as
$BODY$
BEGIN
return (select sum(number_hour)
from remaining_absence_day
where id_user= $1
and id_absence_type=$2
and id_year=$3 );
END;
$BODY$
LANGUAGE 'plpgsql' ;
触发功能(为测试而修改!):
create OR REPLACE function update_absence() returns TRIGGER AS
$BODY$
DECLARE
old_number_hour real;
BEGIN
old_number_hour:=get_remaining_hour(3,2,8);
insert into debugging(col,val) values('old_number_hour', old_number_hour);
return null;
END;
$BODY$
LANGUAGE 'plpgsql' ;
触发器定义:
drop trigger if exists update_absence on absence;
CREATE TRIGGER update_absence
after update of type,duration_hour,duration_day on absence
for each ROW
execute procedure update_absence();
答案 0 :(得分:1)
提供的代码应该有效。
特别奇怪的是,您会看到 0
。如果在remaining_absence_day
中找不到匹配的行,您会看到NULL
,而不是0
。但是如果你在相同的环境中调用具有相同参数的函数,你应该看到相同的结果。
我能想到的其余可能解释:与架构搜索路径混淆。例如:您在另一个模式中有函数get_remaining_hour()
或表remaining_absence_day
的第二个实例。并且您使用search_path
的不同设置调用该函数。
你是否在同一个会话中进行了比较?
或者,因为您使用了AFTER
触发器:表absence
上可能有其他触发器修改了表remaining_absence_day
,这些触发器被触发< em>在你的触发器之前。
我所做的所有其他修改都具有美观性或简化性。
CREATE OR REPLACE FUNCTION get_remaining_hour(id_user_v int
, id_absence_v_type int
, id_year_v int)
RETURNS real AS
$func$
BEGIN
RETURN (
SELECT sum(number_hour)
FROM remaining_absence_day -- referencing the right table? see search_path
WHERE id_user = $1
AND id_absence_type = $2
AND id_year = $3
);
END
$func$ LANGUAGE plpgsql STABLE; -- don't quote the language name
CREATE OR REPLACE FUNCTION update_absence()
RETURNS TRIGGER AS
$func$
BEGIN
INSERT INTO debugging(col, val)
VALUES('old_number_hour', get_remaining_hour(3,2,8)); -- hard coded only for testing?
RETURN null; -- only good for AFTER trigger
END
$func$ LANGUAGE plpgsql;
DROP TRIGGER IF EXISTS update_absence ON absence;
CREATE TRIGGER update_absence
AFTER UPDATE OF type, duration_hour, duration_day ON absence
FOR EACH ROW EXECUTE PROCEDURE update_absence();