Som du kanske har märkt är en regex-baserad metod nästan omöjlig att göra korrekt. Ditt test säger till exempel att 1.234e-5
är inte ett giltigt nummer, när det verkligen är det. Dessutom missade du negativa siffror. Tänk om något ser ut som en siffra, men när du försöker lagra det kommer det att orsaka översvämning?
Istället skulle jag rekommendera att skapa en funktion som faktiskt försöker casta till NUMERIC
(eller FLOAT
om din uppgift kräver det) och returnerar TRUE
eller FALSE
beroende på om den här skådespelaren var framgångsrik eller inte.
Denna kod kommer att helt simulera funktionen 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;
Om du anropar den här funktionen på dina data får du följande resultat:
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)
Det är inte bara mer korrekt och lättare att läsa, det kommer också att fungera snabbare om data faktiskt var en siffra.