2015-03-02 3 views
9

Ho il seguente codice che restituisce un messaggio di errore se il mio valore non è valido. Vorrei dare lo stesso messaggio di errore se il valore fornito non è numerico.Come si può sapere se un valore non è numerico in Oracle?

IF(option_id = 0021) THEN 
     IF((value<10000) or (value>7200000) or /* Numeric Check */)THEN 
      ip_msg(6214,option_name); -- Error Message 
      return; 
     END IF; 
END IF;  

In SQL Server, ho semplicemente utilizzato ISNUMERIC(). Mi piacerebbe fare qualcosa di simile in Oracle. Ad esempio,

IF((!ISNUMERIC(value)) or (value<10000) or (value>7200000)) 
    THEN ... 

risposta

10

Nessuna funzione incorporata. Si potrebbe scrivere un

CREATE FUNCTION is_numeric(p_str IN VARCHAR2) 
    RETURN NUMBER 
IS 
    l_num NUMBER; 
BEGIN 
    l_num := to_number(p_str); 
    RETURN 1; 
EXCEPTION 
    WHEN value_error 
    THEN 
    RETURN 0; 
END; 

e/o

CREATE FUNCTION my_to_number(p_str IN VARCHAR2) 
    RETURN NUMBER 
IS 
    l_num NUMBER; 
BEGIN 
    l_num := to_number(p_str); 
    RETURN l_num; 
EXCEPTION 
    WHEN value_error 
    THEN 
    RETURN NULL; 
END; 

È quindi possibile fare

IF(is_numeric(str) = 1 AND 
    my_to_number(str) >= 1000 AND 
    my_to_number(str) <= 7000) 
+1

Penso che si desidera 'is_numeric (str) = 0 'sopra, se ho capito correttamente il PO (equivalente di'! ISNUMERIC (valore) '). –

+1

@DavidFaber - Suppongo che sia un refuso. Se una stringa non è numerica, non avrebbe senso per poi confrontarla con valori numerici. –

+1

Oh capisco, stai usando AND dove l'OP ha OR. Colpa mia. –

16
REGEXP_LIKE(column, '^[[:digit:]]+$') 

restituisce TRUE se la colonna contiene solo caratteri numerici

+3

Ovviamente, non tutti i numeri sarebbero composti interamente da caratteri numerici. "1.2" è numerico ma contiene un punto (o una virgola a seconda delle impostazioni NLS). "-100" è numerico ma contiene un segno meno. "1.2.3" non è numerico sebbene sia composto interamente da cifre e punti. Il 'regexp_like' potrebbe essere sufficiente se stai davvero cercando di vedere se la colonna contiene interi positivi senza formattazione. –

+1

'123e-5' è anche un numero. –

+1

Questa espressione regolare coprirebbe solo valori interi positivi! –

2

È possibile utilizzare la seguente espressione regolare wh ich corrisponderà numeri interi (ad esempio, 123), i numeri in virgola mobile (12.3), e numeri con esponenti (1.2e3):

^-?\d*\.?\d+([eE]-?\d+)?$ 

Se si desidera accettare + segni così come - segni (come Oracle fa con TO_NUMBER()), è possibile modificare ciascuna occorrenza di - sopra a [+-]. Così si potrebbe riscrivere il blocco di codice di cui sopra come segue:

IF (option_id = 0021) THEN 
    IF NOT REGEXP_LIKE(value, '^[+-]?\d*\.?\d+([eE][+-]?\d+)?$') OR TO_NUMBER(value) < 10000 OR TO_NUMBER(value) > 7200000 THEN 
     ip_msg(6214,option_name); 
     RETURN; 
    END IF; 
END IF; 

Io non sono del tutto certo che avrebbe gestito tutti i valori quindi si consiglia di aggiungere un blocco EXCEPTION o scrivere una funzione personalizzata to_number() come suggerisce @JustinCave.

5

Da Oracle DB 12c Release 2 si potrebbe usare VALIDATE_CONVERSION funzione:

VALIDATE_CONVERSION determina se expr può essere convertito nel tipo di dati specificato. Se expr può essere convertito con successo, allora questa funzione restituisce 1; altrimenti, questa funzione restituisce 0. Se expr restituisce null, questa funzione restituisce 1. Se si verifica un errore durante la valutazione di expr, questa funzione restituisce l'errore.

IF (VALIDATE_CONVERSION(value AS NUMBER) = 1) THEN 
    ... 
END IF;