Jak jste si mohli všimnout, metodu založenou na regulárních výrazech je téměř nemožné provést správně. Váš test například říká, že 1.234e-5
není platné číslo, když tomu tak skutečně je. Také jste vynechali záporná čísla. Co když něco vypadá jako číslo, ale když se to pokusíte uložit, způsobí to přetečení?
Místo toho bych doporučil vytvořit funkci, která se skutečně pokusí přetypovat na NUMERIC
(nebo FLOAT
pokud to váš úkol vyžaduje) a vrátí TRUE
nebo FALSE
podle toho, zda bylo toto obsazení úspěšné nebo ne.
Tento kód bude plně simulovat funkci 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;
Volání této funkce ve vašich datech získá následující výsledky:
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)
Nejen, že je správnější a snáze čitelný, ale bude také fungovat rychleji, pokud data byla ve skutečnosti číslo.