El escenario es el siguiente: tenemos una tabla t con un campo codOpe que es un código de operación y un campo infoOpe que es información sobre la operación. Ambos son varchar, pero sabemos que para un determinado valor de codOpe ('PR') el contenido de infoOpe siempre es numérico, sin excepciones, aunque para otros valores de codOpe no tiene porqué serlo.
Creamos una vista para explotar las operaciones de tipo 'PR':
create view opePR as
select to_number(infoOpe) as infoOpeNum from t
where codOpe='PR'
Perfecto. Oracle es la hostia y funciona al pelo. La vista me devuelve tantas filas como operaciones PR's tengo en mi tabla. Ahora quiero saber cuantos PR's tengo con infoOpe mayor que 100. Vamos a usar nuestra vista:
select * from opePR where infoOpeNum>100
Cuando lanzamos la sentencia Oracle (9.2) nos devuelve un bonito error:
ORA-01722: invalid number
Jarl. Oracle ya no es la hostia. Si la consulta nos devuelve sólo valores numéricos... ¿por qué nos falla cuando escribimos el where?...
El origen del problema es el optimizador de consultas de Oracle. El tener la vista almacenada no significa que primero se ejecute su where (el que nos asegura que el campo es numérico) y luego el where externo, sino que el optimizador combina ambos where para que el plan de ejecución de la consulta sea lo más eficiente posible, y conseguir así una consulta eficiente pero con un pequeño problema: que no funciona.
Solución: indicarle al optimizador que no mezcle los "where":
select /*+ NO_MERGE(t) */
from opePR t where infoOpeNum>100
La consulta será ineficiente, pero funciona, coño. Oracle vuelve a ser la hostia.