PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

isumeric() con PostgreSQL

Come avrai notato, il metodo basato su espressioni regolari è quasi impossibile da eseguire correttamente. Ad esempio, il tuo test dice che 1.234e-5 non è un numero valido, quando lo è realmente. Inoltre, hai perso numeri negativi. Cosa succede se qualcosa sembra un numero, ma quando provi a memorizzarlo causerà un overflow?

Invece, consiglierei di creare una funzione che tenti di eseguire effettivamente il cast su NUMERIC (o FLOAT se la tua attività lo richiede) e restituisce TRUE o FALSE a seconda che questo cast abbia avuto successo o meno.

Questo codice simulerà completamente la funzione 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;

Chiamando questa funzione sui tuoi dati ottieni i seguenti risultati:

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)

Non solo è più corretto e più facile da leggere, ma funzionerà anche più velocemente se i dati fossero effettivamente un numero.