【问题标题】:Stored procedure for the Exponential in postgresqlpostgresql中指数的存储过程
【发布时间】:2012-08-24 19:45:13
【问题描述】:

在 PostgreSQL 中出现错误:

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

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

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

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

【问题讨论】:

  • +1 感谢您提供您的 Pg 版本并清理您之前的问题。

标签: postgresql stored-procedures exponential postgresql-9.0


【解决方案1】:

这是正在发生的事情:

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

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

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

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

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


要捕获异常,请在 PL/PgSQL 中使用 BEGIN ... EXCEPTION

我编写了下面的函数来返回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是通过查找Pg手册中Appendix A. PostgreSQL Error Codes中超出范围的exp得到的SQLSTATE 22003得到的。您将在有关 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 中捕获“超出范围”异常更有效,并且也让您的意图更加清晰。

【讨论】:

  • 您好,难道也不能写存储过程吗?
  • @Sathish 是的,如上所示。不要这样做。这种方法感觉很不对,很痛。你到底为什么要这样做?您要解决的真正问题是什么?似乎您遇到了问题,您已经确定这是解决方案,并且您正在询问如何创建解决方案。什么是根本问题,您要解决的真正问题是什么?
  • @Sathish 感谢您删除您之前在此问题上所做的努力。
  • 很好但是上面的存储过程 crazy_exp(5999.2) ?
  • @Sathish ... 像你说的那样返回零。我不明白你最后的评论在问什么。我也真的认为你应该编辑你的问题并解释为什么你想这样做,它可能有助于提出更清洁/更好的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-26
  • 1970-01-01
  • 2020-07-11
相关资源
最近更新 更多