Postgresql 检查有效输入的触发器
我在postgres数据库中插入了大量来自不同来源的测量数据。数据是一个测量值和一个不确定度(以及许多辅助数据)。问题是,在某些情况下,我得到一个绝对误差值,例如123+/-33,在其他情况下,我得到一个相对误差,作为测量值的百分比,例如123+/-10%。我想用绝对误差存储所有测量值,即后者应存储为123+/-12.3-(此时,我不太关心有效位数) 我的想法是使用触发器来实现这一点。基本上,如果错误为数字,则按原样存储;如果错误为非数字,则检查最后一个字符是否为“%”,在这种情况下,将其与测量值相乘,除以100并存储结果值。我从这里得到了一个isnumeric函数:它工作得很好。但是,当我试图将其转换为触发器时,似乎在触发器触发之前就已经检查了输入的有效性,因此,在我有可能对值执行任何操作之前,插入被中止 我的triggerfunction:(需要进行计算,只需在此处将错误设置为0Postgresql 检查有效输入的触发器,postgresql,triggers,Postgresql,Triggers,我在postgres数据库中插入了大量来自不同来源的测量数据。数据是一个测量值和一个不确定度(以及许多辅助数据)。问题是,在某些情况下,我得到一个绝对误差值,例如123+/-33,在其他情况下,我得到一个相对误差,作为测量值的百分比,例如123+/-10%。我想用绝对误差存储所有测量值,即后者应存储为123+/-12.3-(此时,我不太关心有效位数) 我的想法是使用触发器来实现这一点。基本上,如果错误为数字,则按原样存储;如果错误为非数字,则检查最后一个字符是否为“%”,在这种情况下,将其与测量
create function my_trigger_function()
returns trigger as'
begin
if not isnumeric(new.err) THEN
new.err=0;
end if;
return new;
end' language 'plpgsql';
然后我将其连接到表:
create trigger test_trigger
before insert on test
for each row
execute procedure my_trigger_function();
这样做,我希望得到以下插入的val=123和err=0
insert into test(val,err) values(123,'10%');
但是insert由于“invalid input SYMBOL for type numeric”而失败,必须在触发器有可能看到数据之前触发它(或者我误解了一些基本的东西)。是否可以使新的.err数据类型不可知,或者我是否可以更早地运行触发器,或者我想做的是完全不可能的?使用触发器是不可能的,因为SQL解析器以前失败过 启动触发器时,
NEW.*
列的最终类型已与目标列匹配
最接近的替代方案是提供一个从文本转换为数字的函数,实现自定义语法规则,并将其应用于VALUES
子句:
insert into test(val,err) values(123, custom_convert('10%'));
Daniel回答了我最初的问题,我发现我不得不换一种想法。他关于如何做的建议可能对其他人有用,但我的系统通过直接从数据库获取表名和列名来连接数据库的方式,效果不太好 相反,我在度量表中添加了一个布尔字段relerr
alter table measure add relerr boolean default false;
然后我做了一个触发器,检查relerr是否为真,这表明我试图存储一个相对错误,如果是,它将重新计算错误列(称为prec以表示精度)
然后
create trigger meas_calc_relerr_trigger
before update on measure
for each row
execute procedure calc_fromrel_error();
瞧,通过做一个
INSERT into measure (value,prec,relerr) values(220,10,true);
我将表格填充为220,22,false。插入的值通常不会更新,如果由于某种奇怪的原因发生这种情况,我将能够手动计算prec列。使用触发器是不可能的,因为SQL解析器以前失败过。最接近的替代方法是提供函数
myfunc(text)返回数值
并将其应用到VALUES子句中。谢谢,这正是我所担心的-回到绘图板上…:-/@DanielVérité,如果您将您的推荐改写为答案,我可以接受。
INSERT into measure (value,prec,relerr) values(220,10,true);