PostgreSQLでエラーが発生します:
ERROR: argument for function "exp" too big
SQL state: 22003
Exponentialの保存されたプロシージャを次のように記述する必要があります。
- 関数
exp(value)
「exp」の引数が大きすぎる場合 - 次に0を返します
- それ以外の場合は戻ります
exp(value)
このストアドプロシージャの処理方法を教えてください。
PostgreSQLでエラーが発生します:
ERROR: argument for function "exp" too big
SQL state: 22003
Exponentialの保存されたプロシージャを次のように記述する必要があります。
exp(value)
「exp」の引数が大きすぎる場合exp(value)
このストアドプロシージャの処理方法を教えてください。
これが起こっていることです:
regress=# SELECT exp(NUMERIC '6000');
ERROR: argument for function "exp" too big
に非現実的に大きな値を渡していますexp()
。(double)をオーバーフローするには大きすぎてfloat8
、 としてしか表現できませんNUMERIC
。そこにも限界があり、上に行くと当たるexp(5999)
。
難しい数学については、言語PL/R
のデータベース内埋め込みバージョンであるを試してみてください。R
何をすべきかを言うのは難しいです。なぜなら、クエリが何のためにあるのか、何への入力exp
が想定されているのかなどを実際に説明していないからです.
大きすぎる指数に対して 0 を返すのはちょっとおかしなことです。なんで?
例外をトラップするには、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;
エラーコードは、Pg マニュアルの付録 A. PostgreSQL エラー コードで範囲外から取得したものを参照して取得numeric_value_out_of_range
されました。に関するドキュメントにリンクが表示されます。SQLSTATE 22003
exp
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で「範囲外」の例外をトラップするよりもはるかに効率的であり、意図もより明確になります。