Seperti yang mungkin Anda perhatikan, metode berbasis regex hampir tidak mungkin dilakukan dengan benar. Misalnya, pengujian Anda mengatakan bahwa 1.234e-5
bukan nomor yang valid, padahal sebenarnya. Juga, Anda melewatkan angka negatif. Bagaimana jika sesuatu terlihat seperti angka, tetapi ketika Anda mencoba menyimpannya, itu akan menyebabkan overflow?
Sebagai gantinya, saya akan merekomendasikan untuk membuat fungsi yang mencoba untuk benar-benar mentransmisikan ke NUMERIC
(atau FLOAT
jika tugas Anda memerlukannya) dan mengembalikan TRUE
atau FALSE
tergantung pada apakah pemeran ini berhasil atau tidak.
Kode ini akan sepenuhnya mensimulasikan fungsi 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;
Memanggil fungsi ini pada data Anda mendapatkan hasil sebagai berikut:
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)
Tidak hanya lebih benar dan lebih mudah dibaca, itu juga akan bekerja lebih cepat jika data sebenarnya adalah angka.