sábado, 2 de agosto de 2014

Concatenar un NULL o la parábola del Universo Vacio

Recuerdo que una vez estaba revisando un extraño error en un sistema que había estado funcionado correctamente durante unos meses. De repente y sin motivo aparente, el resultado de una sumatoria de números estaba arrojando valores al azar. Esto no debería pasar jamas en una sumatoria de registro, el resultado siempre debe ser el mismo siempre y cuando los registros a sumar sean los mismo. Pero en este caso la consulta SQL que ejecutaba el cálculo daba resultados extraños en cada ejecución. Para ese momento estaba trabajando en una base de datos MaxDB (SAP-DB), pero la explicación a esto es mas o menos igual para MySQL, PostgreSQL, SQL Server y posiblemente Oracle.

Después de varias horas revisando el problema decidí pedir ayuda a mi mentor de bases de datos, un ingeniero con más de 25 años de experiencia en bases de datos relacionales llamado Arturo Schotborgh. Luego de unos minutos revisando mi consulta, mi mentor encontró un pequeño detalle dentro de los registros de entrada de la sumatoria: Uno de los registros a sumar tenía un valor "NULL". Yo en ese momento había descartado que ese fuera el motivo, sin embargo ese día recibí una cátedra de bases de datos que nunca voy a olvidar.

Mi mentor inició la lección preguntando: "¿Que significa para ti que un campo de un registro tenga asignado un valor NULL?". Le dije, con la poca experiencia que tenia de programación con PHP que para mi significa que es una variable no asignada, es decir, una cadena vacía, un valor cero, un arreglo sin elementos. 

Entonces mi mentor me explicó: 
Un NULL no es un registro vacío, ni una cadena de longitud cero, ni un cero. En bases de datos un NULL significa "la ausencia de un valor". Una cadena de longitud cero es un valor y un cero es un valor. Pero un NULL jamás será un cero y jamás será una cadena vacía. Lo más parecido a un NULL en bases de datos es el Conjunto Vacío o mas bien, un Universo Vacio.
En ese momento le pregunté: "¿si es la ausencia de un valor, entonces por que en la consulta los resultados variaban sólo por la presencia de un NULL?" y me dijo:
El valor de un Universo Vacío no es cero, es infinito, por tanto, si tratas de sumar "algo" más infinito el resultado es "infinito", no es determinable. Si quieres que el resultado de tu consulta sea determinable debes asegurarte de reemplazar el valor NULL de cualquier registro por un valor, por ejemplo, cero.
Luego de esto por medio de la función "coalesce" me encargué de reemplazar los NULL de los campos de la sumatoria por cero y listo! La consulta funcionaba correctamente otra vez. La lección de mi mentor terminó de la siguiente manera:
Siempre que vayas a tratar de realizar una concatenación o una operación matemática con campos de una base de datos, asegúrate que ningún valor sea NULL.
Ahora, luego de 10 años con bases de datos y programación, pienso que esta situación probablemente se originó por la forma como el servidor de base de datos maneja los valores de la consulta en memoria al hacer la sumatoria. Sin embargo la explicación considero que es perfectamente válida. Esta explicación también me ayudo a entender que en PHP un NULL también significa la ausencia de un valor y por tanto, concatenar un NULL con una cadena o número siempre resulta en un NULL.

Así que ya saben, para el caso de MySQL, si tienen que hacer una sumatoria (sum), promedio (avg), o concatenacion (concat), asegúrense que los valores de entrada nunca serán NULL. Si hay posibilidad que puedan serlo, usen la función "ifnull" para reemplazar los NULL por algún valor.



No hay comentarios:

Publicar un comentario en la entrada