Hace unos días intenté explicar como utilizar la función DECODE en Oracle. Es una de las funciones de SQL más utilizadas, pero en muy pocos casos está justificado su uso. Las razones principales para pensárnoslo dos veces antes de utilizar el DECODE son:
1. Oracle permite utilizar la cláusula CASE en el SQL. Esto facilita, sobre todo, las comparaciones numéricas. Todos hemos hecho eso de obtener el signo de una resta para saber qué número es mayor o menor. Un ejemplo de CASE con la tabla de países:
select nombre,
case
when (nombre = 'ESPAÑA') then 'Español'
when (nombre = 'ALEMANIA') then 'Alemán'
when (nombre = 'FRANCIA') then 'Francés'
else 'desonocido'
end ejemplo_case
from paises
2. Estamos escribiendo “a fuego” la tipificación en el propio código. En el momento en que queramos añadir una opción al DECODE (por ejemplo, Italia en nuestro ejemplo), deberemos recompilar el código. No sé vosotros, pero me fastidiaría tener que añadir opciones a un programa ya entregado. Además, compilar no siempre es sencillo. Yo creo que la mejor opción es añadir una tabla de nacionalidades que sea mantenible por el usuario
3. Si escribimos un mismo DECODE en varias partes de un programa, éste debe estar documentado. Si no, nos olvidaremos de “extender” el cambio. Es muy común que, por ejemplo, los resultados de naciones sean diferentes en distintos combos.
4. El DECODE no es ni multilenguaje, ni configurable. Hacer que el programa retorne ‘Spanish’ en lugar de ‘Español’ si el idioma es inglés requiere modificar cada procedimiento donde se utilice este DECODE. En este caso deberíamos esconder la complejidad en una función
En fin, estos son mis principios. Pero como diría Groucho Marx, del cuál se cumplen mañana 31 años de su fallecimiento, si no le gustan, tengo otros.
Artículos relacionados
-
Paco Ros dice:
18 de agosto de 2008 a las 16:03Ya leí el otro día tu comentario sobre el “peligro” del decode y estaba esperando a ver esta nota con respecto a tus argumentos.
Esta vez, querido amigo, voy a discrepar contigo
El problema al que haces referencia no es un problema genérico de DECODE. Es un problema de un uso indebido de Decode para internacionalizar una tabla de países (y supongo que internacionalizar cualquier cosa).Para el caso concreto de la tabla de países, yo prefiero una tabla de países. Sin mantenimiento, ni nada, pero una tabla bien indexada y una FK hacia ella. Si las PKs son descriptivas, ayuda a “leer” la tabla cuando consultas los datos para verlos y comprobar que son correctos.
En el caso que nos ocupa, el DECODE, es una herramienta excelente si se usa bien. El mejor ejemplo que se me ocurre es el método Rozenshtein, que utiliza decode para generar matrices estadísticas con una sola consulta. (http://www.stephenforte.net/default.aspx?date=2003-08-07)
No, Sr. García, no me convencen sus argumentos. Por favor, vuelva a intentarlo
Un abrazo.
–
Paco -
Carlos A. García dice:
18 de agosto de 2008 a las 20:37Ufff
Veo dos cosas positivas:
1. Alguien me está empezando a coger confianza, con la provocación adecuada
2. Veo que hay gente que sabe más que yo
Es decir, después de reconocer mi ignorancia, creo que mi opinión sigue siendo la correcta. No creo que la solución que aportas sea mantenible … es que no es ni entendible por el 99% de los programadores Oracle !!!
Además, si revisas mi post, verás que digo que “en muy pocos casos está justificado su uso”. Reconociendo que en el caso que aportas esté justificado … sí que estarás conmigo en que la mayoría de DECODEs que encontramos en los programas son más parecidos al mío de países-nacionalidades que al de “matriz de estadísticas” .
En fin, simplemente quería advertir sobre una posible mala praxis, que yo creo que, desgraciadamente, está muy extendida
Saludos -
Paco Ros dice:
20 de agosto de 2008 a las 16:12Je, je… Vamos a ver. Será porque llevo demasiado tiempo haciendo cosas con J2EE pero soy muy escrupuloso separando UI, Lógica y datos.
Por ese motivo, soy completamente contrario al uso de una base de datos más allá de para lo que está destinada: almacenar datos.
Eso implica cosas como no usar triggers o no usar PL.
He tenido mil debates al respecto, pero nadie me ha convencido aún de que, salvo por cuestiones de rendimiento puro, sea más conveniente implementar cualquier condición lógica en un programa con un lenguaje de programación dedicado al respecto e independiente de la interfaz o la base de datos.
¿A qué viene esto? Pues a que el caso del Rozenshtein es uno de esos casos donde nos encontraríamos con un problema de rendimiento si intentáramos ejecutar una consulta por columna y montar en memoria una estructura con nuestra matriz o estadística.
Así que, sí, desde ese punto de vista tienes razón: es un caso muy específico y, a menudo, necesario porque hay veces que 12 consultas no son aceptables.
¿Hablamos de mantenibilidad? Espero ansioso tus posts
. Ah! Y, es muy cómodo leer y comentar lo que uno quiere o conoce sobre los posts que se curran otros.
En este caso, conozco soluciones a problemas que me he encontrado, pero las BBDD no son mi fuerte. Creo que, de largo, sabes mucho más que yo
Saludos.
-
Carlos A. García dice:
21 de agosto de 2008 a las 8:28Buenas
Buena manera de empezar la mañana … me has despertado de golpe. Empecemos por el principio: te recomiendo leer un libro muy pequeñito y sencillo de Arthur Schopenhauer. Se titula “Dialéctica erística o el arte de tener razón, expuesta en 38 estratagemas”. Lo vi en la librería de la UIB, y me llamó tanto la atención el título (que por cierto, cambia dependiendo de la traducción) que lo tuve que comprar. En él Schopenhauer incluye una táctica que tu has utilizado: a partir de una premisa cierta extraigo una conclusión que doy por verdadera e inevitable, pero que en realidad no guarda ninguna relación con la premisa. Por ejemplo: “El amarillo es un color chillón, por lo tanto me tengo que comprar un coche”
Tú dices: “creo en la separación de capas, por lo tanto no utilizo pl ni triggers”. Las mismas capas que puedes montar en J2EE son trasladables directamente a pl, excepto, evidentemente, la de presentación. De hecho, si revisas mis posts (si no, ya te lo envío yo) hay uno en el que explico como crear un DAO automáticamente en pl. ¿Nadie te ha convencido sobre las ventajas del pl? No seré yo, que no soy comercial. Yo sé porque lo utilizo: integridad transaccional asegurada, el pl es un lenguaje con una menor barrera de entrada que el JAVA (es más fácil de aprender para un novato), zonas de exclusión (esto ya lo explicaré) y … que hay cosas que se hacen el pl que NO se pueden hacer en JAVA. Un ejemplo: triggers que registran cualquier acción que se realiza sobre una tabla. En el caso en el que lo hemos aplicado esto es crítico: si cualquiera (y digo cualquiera, incluso el informático por detrás) alteran cualquier registro de cualquier tabla, la modificación quedará registrada en una base de datos sólo accesible por el DBA.
Bueno, ya he empezado el día con energía, que me hacía falta.Saludos. A ver si cunde el ejemplo y me dais estopa
-
Araceli dice:
18 de junio de 2009 a las 10:39Tengo una duda…¿cual es la diferencia/ventaja en usar DECODE o CASE WHEN? es que yo de toda la vida he usado la sentencia DECODE, pero ahora veo que se puede usar CASE WHEN y al intentar aplicarla, me resulta igual que hacer un DECODE. Perdonad mi ignorancia.
Un Saludo
-
Carlos A. García dice:
22 de junio de 2009 a las 22:07La única ventaja es la claridad. Además, es más flexible. Por ejemplo, ya no es necesario hacer un SIGN de una resta para ver si un número es mayor que otro. Es más cómodo un when. En cualquier caso, los viejos utilizamos el decode…









Suscribirse a nuestro Twitter
Carlos (02-Aug-2010)
A través de la página en FaceBook de BalearesON, Darío ha enlazado una aplicación de canal del tiempo para Surface. Muy interesante.