3 回答
TA贡献1828条经验 获得超3个赞
您可能会注意到,基于正则表达式的方法几乎不可能正确执行。例如,您的测试说这1.234e-5不是有效数字,而实际上是。另外,您错过了负数。如果某些东西看起来像数字,但是当您尝试存储它会导致溢出怎么办?
相反,我建议创建试图实际转换为的函数NUMERIC(或FLOAT如果您的任务需要它)并返回TRUE或FALSE取决于此转换是否成功的函数。
此代码将完全模拟功能ISNUMERIC():
CREATE OR REPLACE FUNCTION isnumeric(text) RETURNS BOOLEAN AS $$
DECLARE x NUMERIC;
BEGIN
x = $1::NUMERIC;
RETURN TRUE;
EXCEPTION WHEN others THEN
RETURN FALSE;
END;
$$
STRICT
LANGUAGE plpgsql IMMUTABLE;
在您的数据上调用此函数将得到以下结果:
WITH test(x) AS ( VALUES (''), ('.'), ('.0'), ('0.'), ('0'), ('1'), ('123'),
('123.456'), ('abc'), ('1..2'), ('1.2.3.4'), ('1x234'), ('1.234e-5'))
SELECT x, isnumeric(x) FROM test;
x | isnumeric
----------+-----------
| f
. | f
.0 | t
0. | t
0 | t
1 | t
123 | t
123.456 | t
abc | f
1..2 | f
1.2.3.4 | f
1x234 | f
1.234e-5 | t
(13 rows)
如果数据实际上是数字,它不仅更正确,更容易阅读,而且还可以更快地工作。
TA贡献1797条经验 获得超4个赞
我想可能会有这样的看法(这不是对异常处理的滥用),但总的来说,我认为应该为此使用异常处理机制。测试字符串是否包含数字是正常处理的一部分,而不是“例外”。
但是您对不处理指数是正确的。这是正则表达式(下)的第二个刺。我必须追求使用正则表达式的解决方案的原因是,当遇到错误时给出指令退出时,此处提供为“正确”解决方案的解决方案将失败:
SET exit_on_error = true;
当运行SQL脚本组时,并且如果有任何问题/错误我们想立即停止时,我们经常使用它。给出此会话指令后,即使没有遇到“真实”异常,调用isnumeric的“正确”版本也会导致脚本立即退出。
create or replace function isnumeric(text) returns boolean
immutable
language plpgsql
as $$
begin
if $1 is null or rtrim($1)='' then
return false;
else
return (select $1 ~ '^ *[-+]?[0-9]*([.][0-9]+)?[0-9]*(([eE][-+]?)[0-9]+)? *$');
end if;
end;
$$;
TA贡献1872条经验 获得超3个赞
您的问题是小数点两侧的两个0或多个[0-9]元素。您需要|在数字标识行中使用逻辑或:
~'^([0-9]+\.?[0-9]*|\.[0-9]+)$'
这将仅排除小数点作为有效数字。
- 3 回答
- 0 关注
- 560 浏览
添加回答
举报