Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql 检查有效输入的触发器_Postgresql_Triggers - Fatal编程技术网

Postgresql 检查有效输入的触发器

Postgresql 检查有效输入的触发器,postgresql,triggers,Postgresql,Triggers,我在postgres数据库中插入了大量来自不同来源的测量数据。数据是一个测量值和一个不确定度(以及许多辅助数据)。问题是,在某些情况下,我得到一个绝对误差值,例如123+/-33,在其他情况下,我得到一个相对误差,作为测量值的百分比,例如123+/-10%。我想用绝对误差存储所有测量值,即后者应存储为123+/-12.3-(此时,我不太关心有效位数) 我的想法是使用触发器来实现这一点。基本上,如果错误为数字,则按原样存储;如果错误为非数字,则检查最后一个字符是否为“%”,在这种情况下,将其与测量

我在postgres数据库中插入了大量来自不同来源的测量数据。数据是一个测量值和一个不确定度(以及许多辅助数据)。问题是,在某些情况下,我得到一个绝对误差值,例如123+/-33,在其他情况下,我得到一个相对误差,作为测量值的百分比,例如123+/-10%。我想用绝对误差存储所有测量值,即后者应存储为123+/-12.3-(此时,我不太关心有效位数)

我的想法是使用触发器来实现这一点。基本上,如果错误为数字,则按原样存储;如果错误为非数字,则检查最后一个字符是否为“%”,在这种情况下,将其与测量值相乘,除以100并存储结果值。我从这里得到了一个isnumeric函数:它工作得很好。但是,当我试图将其转换为触发器时,似乎在触发器触发之前就已经检查了输入的有效性,因此,在我有可能对值执行任何操作之前,插入被中止

我的triggerfunction:(需要进行计算,只需在此处将错误设置为0

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);