sql - 如何创建函数返回值直至第一个非数字/小数字符

标签 sql postgresql plpgsql postgresql-9.0

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+ 的最佳方式吗?

最佳答案

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

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

Here是一个数据库<> fiddle 。

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

关于sql - 如何创建函数返回值直至第一个非数字/小数字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63032072/

相关文章:

php - SQL获取同组其他用户数据

mysql - CASE 将忽略重复条目

mysql - 复制数据库更改

sql - 触发错误时回滚事务

postgresql - 当数据库连接关闭或丢失时, Hook Postgres 服务器运行代码?

mysql - SQL:三元运算

mysql - 如何在sql中添加同时具有字符串和自动递增数字的ID

sql - 如何通过过滤器有效地获得最小值和最大值?

sql - Postgres 嵌套 if in case 查询

sql - Postgres 函数创建但不执行