Zoals je misschien hebt gemerkt, is een op regex gebaseerde methode bijna onmogelijk om correct te doen. Uw test zegt bijvoorbeeld dat 1.234e-5
is geen geldig nummer, terwijl het dat wel is. Ook heb je negatieve getallen gemist. Wat als iets op een nummer lijkt, maar als je het probeert op te slaan, zal het overlopen?
In plaats daarvan raad ik aan om een functie te maken die daadwerkelijk probeert te casten naar NUMERIC
(of FLOAT
als uw taak dit vereist) en retourneert TRUE
of FALSE
afhankelijk van of deze cast succesvol was of niet.
Deze code simuleert de functie ISNUMERIC()
fully volledig :
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;
Als u deze functie op uw gegevens aanroept, krijgt u de volgende resultaten:
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)
Het is niet alleen correcter en gemakkelijker te lezen, het zal ook sneller werken als gegevens daadwerkelijk een getal waren.