Comme vous l'avez peut-être remarqué, la méthode basée sur les regex est presque impossible à faire correctement. Par exemple, votre test indique que 1.234e-5
n'est pas un nombre valide, alors qu'il l'est vraiment. De plus, vous avez manqué des nombres négatifs. Que se passe-t-il si quelque chose ressemble à un nombre, mais que lorsque vous essayez de le stocker, cela provoque un débordement ?
Au lieu de cela, je recommanderais de créer une fonction qui essaie de convertir en NUMERIC
(ou FLOAT
si votre tâche l'exige) et renvoie TRUE
ou FALSE
selon que ce casting a réussi ou non.
Ce code simulera entièrement la fonction 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;
L'appel de cette fonction sur vos données donne les résultats suivants :
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)
Non seulement il est plus correct et plus facile à lire, mais il fonctionnera également plus rapidement si les données étaient en fait un nombre.