web-dev-qa-db-fra.com

NLS_NUMERIC_CHARACTERS paramètre pour le nombre décimal

J'ai une installation de base de données dans une machine de test et une seconde dans une machine de production. Quand je cours:

select to_number('100,12') from dual 

Ensuite, il donne une erreur dans la machine de test. Cependant, cette déclaration fonctionne assez bien dans la machine de production.

Maintenant, quand je vérifie NLS_NUMERIC_CHARACTERS, je vois ',' (virgule) dans les deux machines. Y a-t-il un autre endroit où je devrais être à la recherche du réglage décimal?

À votre santé!

11
Jaanna

Vous pouvez voir vos paramètres de session actuels en interrogeant nls_session_parameters:

select value
from nls_session_parameters
where parameter = 'NLS_NUMERIC_CHARACTERS';

VALUE                                  
----------------------------------------
.,                                       

Cela peut différer des valeurs par défaut de la base de données, que vous pouvez voir dans nls_database_parameters.

Dans cette session vos erreurs de requête:

select to_number('100,12') from dual;

Error report -
SQL Error: ORA-01722: invalid number
01722. 00000 -  "invalid number"

Je pourrais modifier ma session soit directement avec alter session, soit en m'assurant que mon client est configuré de manière à définir les besoins en termes de chaîne (elle peut être héritée d'un système d'exploitation ou des paramètres régionaux Java, par exemple):

alter session set NLS_NUMERIC_CHARACTERS = ',.';
select to_number('100,12') from dual;

TO_NUMBER('100,12')
-------------------
             100,12 

Dans SQL Developer, vous pouvez définir votre valeur préférée dans Outils-> Préférences-> Base de données-> NLS.

Mais je peux également remplacer ce paramètre de session dans le cadre de la requête, avec le troisième paramètre facultatif nlsparam sur to_number() ; bien que cela rend le second paramètre optionnel fmt également nécessaire, vous devez donc pouvoir choisir un format approprié:

alter session set NLS_NUMERIC_CHARACTERS = '.,';
select to_number('100,12', '99999D99', 'NLS_NUMERIC_CHARACTERS='',.''')
from dual;

TO_NUMBER('100,12','99999D99','NLS_NUMERIC_CHARACTERS='',.''')
--------------------------------------------------------------
                                                        100.12 

Par défaut, le résultat est toujours affiché avec les paramètres de ma session. Le séparateur décimal est donc toujours un point.

26
Alex Poole

Jaanna, les paramètres session de Oracle SQL Developer dépendent de votre ordinateur client, tandis que les paramètresNLSde PL/SQL proviennent du serveur.

Par exemple, le NLS_NUMERIC_CHARACTERS sur l'ordinateur client peut être ',. 'tant qu'il s'agit de' ., 'sur le serveur. 

Ainsi, lorsque vous exécutez un script à partir de PL/SQL et Oracle SQL Developer, le séparateur décimal peut être complètement différent pour le même script, sauf si vous modifiez la session avec votre NLS_NUMERIC_CHARACTERS attendu dans le script. 

Une façon de tester facilement votre paramètre de session consiste à:

select to_number(5/2) from dual;
2
Jonas

Pour connaître le séparateur décimal SESSION, vous pouvez utiliser la commande SQL suivante:

ALTER SESSION SET NLS_NUMERIC_CHARACTERS = ', ';

select SUBSTR(value,1,1) as "SEPARATOR"
      ,'using NLS-PARAMETER' as "Explanation"
  from nls_session_parameters
  where parameter = 'NLS_NUMERIC_CHARACTERS'

UNION ALL

select SUBSTR(0.5,1,1) as "SEPARATOR" 
      ,'using NUMBER IMPLICIT CASTING' as "Explanation"
  from DUAL;

La première commande SELECT trouve le paramètre NLS défini dans la table NLS_SESSION_PARAMETERS. Le séparateur décimal est le premier caractère de la valeur renvoyée.

La deuxième commande SELECT convertit IMPLICITEMENT le nombre 0.5 rationnel en chaîne en utilisant (par défaut) NLS_NUMERIC_CHARACTERS défini au niveau de la session.

Les deux commandes renvoient la même valeur.

J'ai déjà testé la même commande SQL dans le script PL/SQL et c'est toujours la même valeur COMMA ou POINT qui est affichée. Le séparateur décimal affiché dans le script PL/SQL est égal à ce qui est affiché en SQL.

Pour tester ce que je dis, j'ai utilisé les commandes SQL suivantes:

ALTER SESSION SET NLS_NUMERIC_CHARACTERS = ', ';

select 'DECIMAL-SEPARATOR on CLIENT: (' || TO_CHAR(.5,) || ')' from dual;

DECLARE
    S VARCHAR2(10) := '?';
BEGIN

    select .5 INTO S from dual;

    DBMS_OUTPUT.PUT_LINE('DECIMAL-SEPARATOR in PL/SQL: (' || S || ')');
END;
/

La commande la plus courte pour connaître le séparateur décimal est la suivante:

SELECT .5 FROM DUAL;

Cela retourne 0,5 si le séparateur décimal est une COMMA et 0.5 si le séparateur décimal est un POINT. 

0
schlebe