PDF de programación - Guía de NULL en Firebird

Imágen de pdf Guía de NULL en Firebird

Guía de NULL en Firebirdgráfica de visualizaciones

Actualizado el 22 de Junio del 2017 (Publicado el 14 de Enero del 2017)
905 visualizaciones desde el 14 de Enero del 2017
272,9 KB
14 paginas
Creado hace 13a (19/06/2010)
Guía de NULL en Firebird

Comportamiento y dificultades de NULL en Firebird

Paul Vinkenoog

Traducción al castellano de Víctor Zaragoza

22 de julio de 2005 Versión de documento 0.2-es

Introducción
Frecuentemente, preguntas de soporte en las listas de correo de Firebird hablan de
“cosas raras” que pasan con los valores NULL en el SQL de Firebird. El concepto
parece difícil de entender – quizá en parte por el nombre, que sugiere una “nada” que no
puede hacer ningún daño si se lo sumas a un número o lo concatenas al final de un
string. En realidad, realizar esas operaciones devolverán también la expresión NULL.

Este artículo explora el comportamiento de NULL en el SQL de Firebird, apunta fallos
comunes y te enseña como manejar de manera segura expresiones que contengan NULL
o resulten en NULL.

Nota:

Algunas sentencias y ejemplos en esta guía han sido tomados de Firebird Quick Start
Guide, inicialmente publicado por IBPhoenix, ahora parte de Firebird Project.

Qué es NULL?
En SQL, NULL no es un valor. Es un estado que indica que el valor de ese item es
desconocido o no existente. No es cero o blanco o una “cadena vacía” y no se comporta
como ninguno de esos valores. Pocas cosas en SQL llevan a tanta confusión como
NULL, y será difícil de entender mientras no entiendas la siguiente simple definición:
NULL significa desconocido.

Déjame repetirlo:
NULL significa desconocido.

Retén esta línea en tu mente mientras leas el resto de este artículo y verás como muchos
de los resultados que parecen absolutamente ilógicos que obtengas con NULL,
prácticamente se autoexplicarán.
NULL en expresiones
Como muchos de nosotros hemos encontrado, para nuestro disgusto, NULL es
contagioso: úsalo en una expresión numérica, texto o fecha/hora y el resultado siempre
es NULL. Úsalo en una expresión lógica y el resultado depende del tipo de operación y
el resto de valores implicados.

Por cierto, nota que en versiones anteriores a Firebird 2.0 es normalmente ilegal usar la
constante NULL directamente en operaciones o comparaciones. Cuando veas NULL en
las expresiones siguientes, léelas como “un campo, variable u otra expresión que
resuelve en NULL”.

Expresiones que devuelven NULL
Las expresiones en esta lista siempre devuelven NULL.

• 1 + 2 +3 + NULL
• ‘Hogar ‘ || ‘dulce ‘ || NULL
• MiCampo = NULL
• MiCampo <> NULL
• NULL = NULL
• not (NULL)

Si tienes dificultades en entender por qué, recuerda que NULL significa “desconocido”.
Además mira en la siguiente tabla donde hay explicaciones por caso. En la tabla, no
hemos escrito NULL en las expresiones (como ya hemos dicho, es, a menudo, ilegal); en
vez de ello, hemos usado dos entidades A y B que son ambas NULL. A y B pueden ser
campos, variables o subexpresiones enteras en su derecho – como son NULL, se
comportan de la misma manera que expresiones cerradas.

Porque:

Tabla 1. Operaciones sobre entidades NULL A y B
Si A y B son NULL, entonces:
1 + 2 + 3 + A
‘Hogar ‘ || ‘dulce ‘ || NULL
MiCampo = A
MiCampo <> A
A = B
Not (A)

Es:
NULL
Si A es desconocido, entonces 6+A también es
desconocido
NULL
Si A es desconocido, entonces ‘Dulce hogar‘ || A
es también desconocido
NULL
Si A es desconocido, no puedes decir que
MiCampo tenga el mismo valor…
NULL
...ni puedes decir que MiCampo tenga distinto
valor
NULL Con A y B desconocidos, es imposible saber si
NULL

son iguales
Si A es desconocido, su inverso también

NULL en expresiones booleanas
Hemos visto que not(NULL) devuelve NULL. Para los operadores and y or, las
cosas son un poco más complicadas:
• NULL or false = NULL
• NULL or true = true
• NULL or NULL = NULL
• NULL and false = false
• NULL and true = NULL
• NULL and NULL = NULL

El SQL de Firebird, no tiene un dato de tipo booleano (lógico); no hay unas constantes
true o false existentes. En la columna de la izquierda de la siguiente tabla (true) and
(false) representan expresiones que devuelven true/false;

Porque:

Tabla 2. Operaciones lógicas (booleanas) sobre una entidad NULL A
Si A es NULL, entonces:
A or false
A or true
A or A
A and false
A and true
A and A

Es:
NULL
True
NULL
False “A y false” es siempre false. El valor de A no
NULL
NULL

“A or false” siempre tiene el valor de A, que es
desconocido
“A or true” siempre es true. El valor de A no
importa
“A or A” siempre equivale a A, que es NULL

importa
“A y true” siempre tiene el valor de A el cuál es
desconocido
“A and A” siempre equivale a A, que es NULL

Todas estas expresiones están en concordancia con la lógica booleana. El hecho de que,
para calcular “X or true” y “X and false”, simplemente no necesites saber el
valor de X, es también la base de una característica que conocemos en varios lenguajes
de programación: evaluación de circuitos cortos booleanos.

Más lógica (o no)
Los resultados de circuitos cortos obtenidos arriba, pueden llevarte a las siguientes
ideas:


0 veces X equivale a 0 para cada X. Por tanto, igual que el valor de X es
desconocido, 0 * X es 0. (Nota: esto sólo sucede si el tipo de dato de X sólo
contiene números, no NaN o infinitos).

• La cadena vacía está ordenada lexicográficamente antes de cada otra cadena. Por

tanto S >= ‘’ es verdad siempre independientemente del valor de S.

• Cada valor equivale a sí mismo, independientemente de si es desconocido o no.
Por tanto, aunque A = B justificadamente se devuelve NULL si A y B son
entidades NULL diferentes, A = A siempre devuelve true, igual que A es NULL.

¿Cómo está esto implementado en el SQL de Firebird? Bueno, siento informarte que, a
pesar de esta convincente lógica – y la analogía con los resultados explicados arriba –
las siguientes expresiones se resuelven todas con NULL:

• 0 * NULL
• NULL >= ‘’
• ‘’ <= NULL
• A = A (con A como un campo o variable NULL)

Demasiado para la coherencia.

NULL en funciones agregadas
En funciones agregadas como COUNT, SUM, AVG, MAX, y MIN, NULL se maneja de
manera diferente: para calcular el resultado, sólo se tienen en consideración los campos
con valores no-NULL. Esto es, si tienes esta tabla:

Sueldo
37
<NULL>
5
12
<NULL>

Nombre
Juan
Perico
Andrés
Roberto
Antonio

MiTabla
ID
1
2
3
4
5
… la sentencia select sum(Sueldo) from MiTabla devuelve 54, que es
37+5+12. Si sumáramos todos los valores, el resultado debería haber sido NULL. Para
AVG, los campos no-NULL son sumados y la suma dividida entre el número de campos
no-NULL.
Hay una excepción en esta regla: COUNT(*) devuelve el número de todas las filas,
incluidas todas aquellas con campos en NULL. Pero COUNT(NombreDeCampo) se
comporta como las otras funciones agregadas y cuenta aquellas filas que tienen campos
con contenido no-NULL.
Otra cosa a tener en cuenta: COUNT(*) y COUNT(NombreDeCampo) jamás
devuelven NULL: si no hay filas en el grupo, ambas funciones devuelven 0. Además,
COUNT(NombreDeCampo) devuelve 0 si todos los NombreDeCampo del grupo son
NULL. Las otras funciones agregadas devuelven NULL en tales casos. Ten en cuenta que
SUM devuelve NULL si se usa en un grupo de registros vacío, lo que es contrario a la
lógica común.
Manejo de NULL en UDF’s
Las UDF’s (User Defined Functions o Funciones Definidas por el Usuario) son
funciones no internas en el motor, por tanto definidas en módulos separados. Firebird
viene con dos librerías UDF: ib_udf (heredada de Interbase) y fbudf. Puedes agregar
más librerías, por ejemplo comprándolas o descargándotelas o bien escribiéndolas tú
mismo. Las UDF no pueden ser usadas “fuera de la caja”, deben ser “declaradas” en la
base de datos primero. Esto es cierto incluso con las UDF que vienen con Firebird.

Conversiones NULL <-> no-NULL no deseadas
Enseñarte como declarar, escribir y usar UDF’s está fuera del ámbito de esta guía. No
obstante, debemos avisarte de que las UDF’s pueden efectuar, ocasionalmente,
conversiones NULL no esperadas. Esto puede, en ocasiones, resultar de introducir un
valor NULL y su conversión a un valor normal y en otra ocasiones en la “nulificación”
de un valor válido de entrada ‘’ (una cadena vacía).

La principal causa de este problema es la llamada “a la antigua usanza” de la UDF. No
es posible pasar un valor NULL como entrada a la función. Cuando una UDF como
LTRIM (recortar por la izquierda) se llama con un argumento NULL, el argumento es
pasado a la función como una cadena vacía. Desde dentro de la función no hay manera
de decir si el argumento pasado es una cadena vacía real o un valor NULL. ¿Entonces

qué hace el implementador de la función? Tiene que tomar una decisión: o bien tomar el
argumento como entró o asumir que es un NULL y tratarlo acorde a ello.
Dependiendo del tipo de dato del resultado, devolver NULL es posible igual que
recibirlo como argumento no lo es. De este modo, estas situaciones inesperadas pueden
suceder:

• Puedes llamar a una UDF con un argumento NULL, ésta lo recibe como un 0 o
como una cadena vacía ‘’. Por medio de la función, este valor no vuelve a ser
NULL: el resultado es un valor no-NULL.

• Puedes llamar a una UDF con un argumento válido como 0 o ‘’ (cadena vacía).
Se pasa el argumento “como es” (obviamente), pero la función considera que el
argumento realmente representa un NULL, lo trata como un agujero negro y
devuelve un NULL.

Ambas conversiones no son deseadas, pero la segunda probablemente más que la
primera (mejor validar algo que es NULL que “nulificar” un valor válido). Volviendo a
nuestro ejemplo con LTRIM: hasta e incluyendo Firebird 1.0.3, esta función devolvía
NULL si se le pasaba como argumento una cadena vacía. Desde la versión 1.5, nunca
devuelve NULL. En estas recientes versiones, las cadenas NULL son “TRIMeadas” a
cadenas vacías – lo cual es incorrecto, pero considerado el menos malo de los dos casos;
en el caso anterior, c
  • Links de descarga
http://lwp-l.com/pdf1830

Comentarios de: Guía de NULL en Firebird (0)


No hay comentarios
 

Comentar...

Nombre
Correo (no se visualiza en la web)
Valoración
Comentarios...
CerrarCerrar
CerrarCerrar
Cerrar

Tienes que ser un usuario registrado para poder insertar imágenes, archivos y/o videos.

Puedes registrarte o validarte desde aquí.

Codigo
Negrita
Subrayado
Tachado
Cursiva
Insertar enlace
Imagen externa
Emoticon
Tabular
Centrar
Titulo
Linea
Disminuir
Aumentar
Vista preliminar
sonreir
dientes
lengua
guiño
enfadado
confundido
llorar
avergonzado
sorprendido
triste
sol
estrella
jarra
camara
taza de cafe
email
beso
bombilla
amor
mal
bien
Es necesario revisar y aceptar las políticas de privacidad