web-dev-qa-db-fra.com

Comment savoir si une valeur n'est pas numérique dans Oracle?

J'ai le code suivant qui renvoie un message d'erreur si ma valeur n'est pas valide. Je voudrais donner le même message d'erreur si la valeur donnée n'est pas numérique.

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;      

Dans SQL Server, j'ai simplement utilisé ISNUMERIC(). Je voudrais faire quelque chose de similaire dans Oracle. Tel que,

IF((!ISNUMERIC(value)) or (value<10000) or (value>7200000))
    THEN ...
15
Kyle Williamson
REGEXP_LIKE(column, '^[[:digit:]]+$')

renvoie VRAI si la colonne ne contient que des caractères numériques

Il n'y a pas de fonction intégrée. Vous pourriez en écrire 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;

et/ou

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;

Vous pouvez ensuite faire

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

Si vous utilisez Oracle 12.2 ou une version ultérieure, des améliorations ont été apportées à to_number fonction que vous pourriez exploiter

IF( to_number( str default null on conversion error ) >= 1000 AND
    to_number( str default null on conversion error ) <= 7000 )
14
Justin Cave

De Oracle DB 12c Release 2 vous pouvez utiliser la fonction VALIDATE_CONVERSION:

VALIDATE_CONVERSION détermine si expr peut être converti dans le type de données spécifié. Si expr peut être converti avec succès, cette fonction renvoie 1; sinon, cette fonction renvoie 0. Si expr est évalué à null, cette fonction renvoie 1. Si une erreur se produit lors de l'évaluation de expr, cette fonction renvoie l'erreur.

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

démo db <> violon

14
Lukasz Szozda

Vous pouvez utiliser l'expression régulière suivante qui fera correspondre des entiers (par exemple, 123), Des nombres à virgule flottante (12.3) Et des nombres avec des exposants (1.2e3):

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

Si vous souhaitez accepter les signes + Ainsi que les signes - (Comme Oracle le fait avec TO_NUMBER()), vous pouvez remplacer chaque occurrence de - Ci-dessus par [+-]. Vous pouvez donc réécrire votre bloc de code ci-dessus comme suit:

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;

Je ne suis pas tout à fait certain que cela gérerait toutes les valeurs, vous pouvez donc ajouter un bloc EXCEPTION ou écrire une fonction to_number() personnalisée comme le suggère @JustinCave.

4
David Faber

La meilleure réponse que j'ai trouvée sur Internet:

SELECT case when trim(TRANSLATE(col1, '0123456789-,.', ' ')) is null
            then 'numeric'
            else 'alpha'
       end
FROM tab1;
3
TechDo