我有两个返回良好值的函数。但是当我在触发器内部调用这些函数时,它们总是返回 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
作为结果特别奇怪。如果在 remaining_absence_day
中找不到匹配的行,您将看到 NULL
,而不是 0
。但是,如果您在相同的环境中使用相同的参数调用该函数,您应该会看到相同的结果。
我能想到的剩下的可能解释:混淆了模式搜索路径。例如:您在不同的架构中有函数 get_remaining_hour()
或表 remaining_absence_day
的第二个实例。并且您使用 search_path
的不同设置来调用该函数。
您是否在同一 session 中进行了比较?
或者,由于您使用的是 AFTER
触发器:表 absence
上可能存在修改表 remaining_absence_day 的其他触发器
,在您的触发器之前触发。
我所做的所有其他修改都是装饰性的或轻微的简化。
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();
关于sql - 函数在触发器内部返回错误值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39223746/