2

val 函数应返回从字符串到第一个非数字字符的数值,同时考虑第一个小数点:

val('1,2TEST')  should return 1.2
val('1,2,3')  should return 1.2
val('-1,2,3')  should return -1.2
val('')  shound return 0

我试过了

CREATE OR REPLACE FUNCTION public.VAL(value text)
  RETURNS numeric AS
$BODY$
SELECT coalesce(nullif('0'||substring(Translate($1,',','.'), '^-?[0-9]+\.?[0-9]*$'),''),'0')::numeric;
$BODY$ language sql immutable;

但如果字符串包含 % 字符,

select val('1,2%')

返回 0。

如何强制它返回 1.2 ?它应该从 Postgres 9 开始工作

更新

支持 9.5 的 Gordon Fiddle 为非数字字符串返回 null。我使用包装器解决了它:

CREATE OR REPLACE FUNCTION public.VALwithNull(value text)
  RETURNS numeric AS
$BODY$
SELECT    replace( (regexp_matches($1, '^-?[0-9]+,*[0-9]*'))[1], ',', '.') ::numeric;
$BODY$ language sql immutable;

CREATE OR REPLACE FUNCTION public.VAL(value text)
  RETURNS numeric AS
$BODY$
SELECT coalesce( VALwithNull($1) ,0) ;
$BODY$ language sql immutable;

select  val('') , val('test'), val('-77,7%')

这是支持 9.0+ 的最佳方式吗?

4

1 回答 1

3

我认为这个正则表达式可以满足您的要求:

replace( (regexp_match($1, '^-?[0-9]+,*[0-9]*') )[1], ',', '.')

是一个 db<>fiddle。

您也可以使用regexp_matches(). 它在这种情况下做同样的事情。

于 2020-07-22T10:26:47.453 回答