2011-04-05 50 views
7

Necesito convertir en el procedimiento de string a decimal con separador decimal fijo . independiente de las configuraciones de cultivo. Luego, sé que el número decimal está limitado solo con 6 lugares decimales después de . y no hay límite en el número de dígitos antes del .. El uso de documentación de Oracle y sus ejemplos de cadenas de formato que tengo ahora solo esta solución:Cómo convertir de una cadena a un número en Oracle utilizando la función TO_NUMBER con un punto decimal fijo char?

v_number := TO_NUMBER(v_string, '9999999999999999999999999999999999D999999', 'NLS_NUMERIC_CHARACTERS = ''. '''); 

Número de caracteres antes de 9D es el número máximo permitido. Encuentro esta cadena de formato como bastante horrible. ¿Hay alguna cadena de formato mejor para esta conversión general o alguna forma de omitir el segundo parámetro de función? En general, solo necesito pasar al parámetro NLS de la función para decirle que solo quiero convertir con el separador decimal ., pero el segundo parámetro también es obligatorio en ese caso.

+0

Si el número en el formulario de cadena es siempre como '9999.99999' ¿por qué no simplemente usa TO_NUMBER()? ¿Quieres poner la restricción de tener 6 dígitos después del decimal? – Chandu

+1

@cybernate: 'to_number (: X)' analizará X en la configuración NLS de la sesión, que podría tener un separador numérico diferente de "." –

+0

@Vincent: Thx para la aclaración ... – Chandu

Respuesta

7

No puede llamar a la función to_number con el tercer parámetro y no el segundo. Sugeriría poner la cadena de formato "feo" en un paquete constante y olvidarlo.

También puede usar dbms_session.set_nls para modificar su configuración de NLS y poder usar to_number sin argumentos.

+1

+1 ... o, usando la misma línea de pensamiento, puede crear su propia función (en paquete) "our_to_number", y ocultar los detalles de implementación por completo. –

+0

Probablemente la solución más clara. Gracias por asegurarme de que estoy en el camino correcto. – Tom

0
CREATE OR REPLACE FUNCTION IS_NUMBER(P_VAR IN VARCHAR2) 
RETURN NUMBER 
IS 
    P_NUMBER NUMBER := 0; 
    RIG VARCHAR2(10) := ''; 
    FORMAT VARCHAR2(100) := '999999999999D999999999999'; 
    RES VARCHAR2(100) := ''; 
BEGIN 
    SELECT VALUE INTO RIG 
    FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER = 'NLS_NUMERIC_CHARACTERS'; 
IF SUBSTR(RIG,1,1) = '.' THEN 
RES := REPLACE(P_VAR,',','.'); 
ELSE 
RES := REPLACE(P_VAR,'.',','); 
END IF; 
P_NUMBER := TO_NUMBER(RES,FORMAT,'NLS_NUMERIC_CHARACTERS='''||RIG||''''); 
P_NUMBER := ROUND(P_NUMBER,5); --FIVE DIGITS AFTER DECIMAL POINT IS ENOUGH 
RETURN P_NUMBER; 
EXCEPTION 
WHEN OTHERS THEN RETURN -1; 
END; 
+2

¿Podría escribir su comentario en inglés en lugar de en ruso? – j0k

+0

ПЯТЬ ЗНАКОВ ПОСЛЕ ЗАПЯТОЙ ДОСТАТОЧОО = Cinco decimales son suficientes. –

-3
select to_number(' 12.5 ') + to_number(' 12 ') from dual; 
+0

¿Cómo responde esto la pregunta? –

1

maneja tanto coma y el punto.

FUNCTION to_number2(p_num_str VARCHAR2) RETURN NUMBER AS 
BEGIN 
    RETURN TO_NUMBER(REPLACE(p_num_str, ',', '.'), '999999999999D999999999999', 'NLS_NUMERIC_CHARACTERS=''.,'''); 
END; 
Cuestiones relacionadas