Wie Sie vielleicht bemerkt haben, ist es fast unmöglich, eine auf Regex basierende Methode korrekt auszuführen. Ihr Test sagt beispielsweise, dass 1.234e-5
ist keine gültige Nummer, wenn es wirklich ist. Außerdem haben Sie negative Zahlen übersehen. Was ist, wenn etwas wie eine Zahl aussieht, aber beim Versuch, es zu speichern, einen Überlauf verursacht?
Stattdessen würde ich empfehlen, eine Funktion zu erstellen, die versucht, tatsächlich in NUMERIC
umzuwandeln (oder FLOAT
wenn Ihre Aufgabe es erfordert) und gibt TRUE
zurück oder FALSE
je nachdem, ob dieser Cast erfolgreich war oder nicht.
Dieser Code simuliert vollständig die Funktion 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;
Wenn Sie diese Funktion für Ihre Daten aufrufen, erhalten Sie folgende Ergebnisse:
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)
Es ist nicht nur korrekter und einfacher zu lesen, es funktioniert auch schneller, wenn die Daten tatsächlich eine Zahl sind.