Concatenar un NULL o la parábola del Universo Vacio

Concatenar un NULL o la parábola del Universo Vacio

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.

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.

Publicado 20 Oct 2017 por
Jonnathan Gutierrez
Artículo original publicado en:
El día que aprendí PHP

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 mismos. 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 qué en la consulta los resultados varían 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. Es como dividir un número entre cero, no sabes cuanto será el resultado. 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 ceros 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 (la suma de valores se mezclaba con direcciones de memoria de los valores nulos, basura o valores aleatorios en RAM). 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.