Như bạn có thể nhận thấy, phương pháp dựa trên regex hầu như không thể thực hiện chính xác. Ví dụ:kiểm tra của bạn cho biết rằng 1.234e-5
không phải là số hợp lệ, khi nó thực sự là như vậy. Ngoài ra, bạn đã bỏ lỡ các số âm. Điều gì sẽ xảy ra nếu một cái gì đó giống như một con số, nhưng khi bạn cố gắng lưu trữ nó, nó sẽ gây ra tràn?
Thay vào đó, tôi khuyên bạn nên tạo hàm cố gắng thực sự truyền đến NUMERIC
(hoặc FLOAT
nếu nhiệm vụ của bạn yêu cầu) và trả về TRUE
hoặc FALSE
tùy thuộc vào việc diễn viên này có thành công hay không.
Đoạn mã này sẽ mô phỏng đầy đủ hàm 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;
Gọi hàm này trên dữ liệu của bạn sẽ nhận được kết quả sau:
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)
Nó không chỉ chính xác hơn và dễ đọc hơn mà còn hoạt động nhanh hơn nếu dữ liệu thực sự là một số.