postgresql中Exponential的存储过程



在PostgreSQL中,我得到了错误:

ERROR: argument for function "exp" too big
SQL state: 22003

我需要为Exponential编写一个存储过程:

  • 如果exp(value)抛出函数"exp"的参数过大
  • 然后返回0
  • 否则返回exp(value)

请帮助我如何处理此存储过程。

这就是正在发生的事情:

regress=# SELECT exp(NUMERIC '6000');
ERROR:  argument for function "exp" too big

您正在向exp()传递一个不切实际的大值。它太大了,无法溢出float8(double),只能表示为NUMERIC。即使在那里,也有一个极限,当你超过exp(5999)时,你就会达到它。

对于硬数学,您可能想尝试PL/R,这是R语言的数据库嵌入式版本。

很难说该怎么做,因为您还没有真正解释查询的目的,exp的输入应该是什么,等等。

为一个太大的指数返回零有点疯狂。为什么?


要捕获异常,请使用BEGIN。。。PL/PgSQL中出现异常。

我已经编写了下面的函数来返回NaN("不是数字")而不是零,因为我认为返回零是完全错误的。如果需要,可以更改它。返回NULL也可能有点道理。

CREATE OR REPLACE FUNCTION exp_if_possible(numeric) RETURNS numeric as $$
BEGIN
    RETURN exp($1);
EXCEPTION
    WHEN numeric_value_out_of_range THEN
        RETURN 'NaN';
END;
$$ LANGUAGE 'plpgsql' IMMUTABLE;

错误代码numeric_value_out_of_range是通过查找附录A中超出范围的exp中的SQLSTATE 22003获得的。Pg手册中的PostgreSQL错误代码。您将在有关BEGIN ... EXCEPTION的文档中看到它的链接。


我最初说,如果要完成,就应该通过测试输入来完成,但我认为我错了。不能保证限制将是exp(6000),所以使用异常处理是正确的,即使它会很慢和笨拙。我将在几秒钟内用异常处理版本更新此响应。

CREATE OR REPLACE FUNCTION crazy_exp(numeric) RETURNS numeric AS $$
-- exp(6000) and above will throw 'argument for function "Exp" too big
-- For such cases, return zero because [insert explanation here]
SELECT CASE WHEN $1 < 6000 THEN exp($1) ELSE 0 END;
$$ LANGUAGE 'sql' IMMUTABLE;
CREATE OR REPLACE FUNCTION crazy_exp(float8) RETURNS float8 AS $$
-- float8 goes out-of-range above about exp(600)
SELECT CASE WHEN $1 <= 600 THEN exp($1) ELSE 0 END;
$$ LANGUAGE 'sql' IMMUTABLE;

这比在PL/PgSQL中捕获"超出范围"的异常要高效得多,也让您的意图更加清晰。

相关内容

  • 没有找到相关文章

最新更新