2012-03-27 20 views
7

Encontré este comportamiento extraño y estoy rompiendo mi cerebro con esto ... ¿alguien tiene alguna idea?Seleccionar cadena como número en Oracle

Oracle 10g: Tengo dos tablas diferentes, ambos tienen esta columna denominada "TESTCOL" como Varchar2 (10), no anulable.

Si realizo esta consulta en tabla1, consigo los resultados apropiados:

select * from table1 where TESTCOL = 1234; 

Nota que específicamente no estoy poniendo '1234' ... no es un error tipográfico, que es una consulta generada dinámica e intentaré no cambiarla (al menos no en el futuro cercano).

Pero, si me quedo la misma consulta, en tabla2, me sale este mensaje de error:

ORA-01722: Invalid number 

Ambas consultas se ejecutan en la misma sesión, la misma base de datos.

He estado uniendo estas dos tablas con esa columna y la unión funciona bien, el único problema aparece cada vez que intento usar esa condición.

¿Alguna idea sobre lo que podría ser diferente de una tabla a otra?

Gracias de antemano.

Respuesta

22

Si TESTCOL contiene elementos no numéricos, Oracle puede tener problemas al convertir las entradas TESTCOL en números. Porque, lo que hace internamente, es la siguiente:

select * from table1 where TO_NUMBER(TESTCOL) = 1234; 

Si está tan seguro de que 1234 no se puede expresar como VARCHAR literal, entonces prueba este lugar, con el fin de comparar los valores varchar, en lugar de los numéricos:

select * from table1 where TESTCOL = TO_CHAR(1234); 
3

Estás jugando los peligros de la conversión de tipos implícita aquí.

Con la expresión testcol = 1234 indica que desea tratar testcol como una columna numérica, por lo que Oracle intenta convertir todos los valores de esa columna en un número.

ORA-01722 se produce porque aparentemente al menos un valor en esa columna es no un número.

Aunque afirme que esto es "no es un error tipográfico" de hecho es uno. Es un error sintáctico.

Tendrá que declarar el parámetro como una cadena literal utilizando comillas simples: where testcol = '1234'

Creación de una condición correcta es la única solución a su problema.

4

Bien obvio TABLE2.TESTCOL contiene valores que no son números.La comparación de una cadena con un literal numérico genera una conversión implícita. Así que cualquier valor en HICH TESTCOL no se puede convertir a un número va a lanzar ORA-1722.

No le golpeó cuando se comparan las dos mesas porque está comparando cadenas.

lo que tiene un par de opciones, neiher de los cuales se va a gustar. La respuesta más obvia es para limpiar los datos de modo TABLA2 hdoesn't no contiene valores numéricos. Idealmente, debería combinar esto con cambiar la columna a un tipo de datos numéricos. De lo contrario, puede modificar el generador para que produzca código que pueda ejecutar contra un modelo de datos shonky. En este caso, eso significa que los literales de envoltura en comillas si la columna asignada tiene un tipo de datos de caracteres.

-1

El siguiente debería funcionar. Simplemente reemplace el "tu donde".

select * 
from table1 
where (select TO_NUMBER(TESTCOL) 
     from table2 
     where "your where") = 1234; 
Cuestiones relacionadas