Firebird Documentation Index → Guía de NULL en Firebird → Trabajando con NULLs |
Esta sección contiene trucos prácticos y ejemplos que pueden ser
usados por ti en tu trabajo diario con NULL
s.
En muchas ocasiones, no tendrás que tomar especiales medidas para
campos o variables que puedan ser NULL
. Por
ejemplo, si haces esto:
select * from Clientes where Ciudad = 'Valencia'
probablemente no quieras ver los clientes cuya ciudad no está especificada. Igualmente:
if (Edad >= 18) then PuedeVotar = 'Si'
no incluye gente que tenga la edad desconocida, que es también defendible. Pero:
if (Edad >= 18) then PuedeVotar = 'Si'; else PuedeVotar = 'No';
no parece correcto: si no sabes la edad de una persona, no puedes explícitamente denegarle el derecho a votar. Peor es esto:
if (Edad < 18) then PuedeVotar = 'No'; else PuedeVotar = 'Si';
que no tiene el mismo efecto que la anterior. Si algunos de las
edades NULL
son, en realidad, menores de 18, ¡les
estás dando derecho a votar!
La manera correcta es comprobar NULL
específicamente:
if (Edad is null) then PuedeVotar = 'No definido'; else if (Edad >= 18) then PuedeVotar = 'Si'; else PuedeVotar = 'No';Nota
else
siempre se refiere al últimoif
en el mismo bloque. Pero es a menudo bueno evitar confusiones poniendo las palabras clavebegin...end
alrededor de grupos de líneas. No lo he hecho aquí para escribir el menor número de líneas posible. Y entonces he compensado esa economización escribiendo esta nota ;-)
A veces quieres saber si dos campos o dos variables son lo mismo y
quieres considerarlos lo mismo si ambas son NULL
.
La manera correcta de comprobarlo es esta:
if (A = B or A is null and B is null) then...
O, si quieres situar la preferencia de operaciones explícitamente:
if ((A = B) or (A is null and B is null)) then...
¡Atención!: Si solo una de A o B es NULL
, la
comparación resulta NULL
, no
false
. Es correcto en una sentencia
if
, y aún podemos añadir una cláusula
else
que se ejecutará si A y B no son iguales
(incluyendo cuando una es NULL
y la otra
no):
if (A = B or A is null and B is null) then ...código a añadir si A es igual a B... else ...código a añadir si A y B son diferentes...
Pero no tengas la brillante idea de invertir la expresión y usarla en una comparación de no igualdad (como yo hice una vez):
/* ¡No hagas esto! */ if (not(A = B or A is null and B is null)) then ...código a añadir si A es distinto a B...
El código anterior funciona correctamente si A y B son ambas
NULL
o ambas no-NULL
. Pero
falla al ejecutar la cláusula then
si sólo una de
ellas es NULL
.
Si sólo quieres que se haga algo si A y B son diferentes, usa
cualquiera de las expresiones correctas anteriores y escribe una
instrucción muerta (que no causará ningún efecto) en la cláusula
then
, o usa esta expresión:
/* Esta es una expresión correcta de no igualdad: */ if (A <> B or A is null and B is not null or A is not null and B is null) then...
En triggers, es a menudo útil saber si cierto campo ha cambiado
(incluyendo que se haya convertido de NULL
a
no-NULL
o viceversa) o sigue siendo igual. Esto
es sólo un caso especial de comprobar la (des)igualdad de dos campos.
Usa New.Nombrecampo y Old.Nombrecampo para A y B.
if (New.Trabajo = Old.Trabajo or New.Trabajo is null and Old.Trabajo is null) then ...El campo Trabajo es igual... else ...El campo Trabajo ha cambiado...
Firebird 1.5 tiene una función que puede convertir
NULL
a casi cualquier otra cosa. Esto te habilita
para hacer conversiones “on-the-fly” y usar el resultado
en un tratamiento posterior, sin la necesidad de utilizar la
construcción “if (MiExpresion is null)
then
”. La función se llama
COALESCE
y la puedes llamar así:
COALESCE(Expr1, Expr2, Expr3, ...)
COALESCE
devuelve el primer valor
no-NULL
de la lista de argumentos. Si todas las
expresiones son NULL
, devuelve
NULL
.
Así es como puedes usar COALESCE
para
construir el nombre completo de una persona desde el nombre, segundo
nombre y primer apellido, asumiendo que algunos segundos nombres
puedan estar en NULL
:
select Nombre || coalesce(' ' || Nombre2, '') || ' ' || Apellido from Personas
O para crear un nombre tan informal como sea posible de una
tabla que incluya también apodos y asumiendo que tanto el apodo como
el primer nombre pueden ser NULL
:
select coalesce (Apodo, Nombre, 'Sr./Sra.') || ' ' || Apellido from OtrasPersonas
COALESCE
te ayudará sólo en situaciones
donde NULL
puede ser tratado como otros valores
posibles del tipo de dato. Si NULL
necesita un
manejo especial, como en el ejemplo de “derecho a votar”
usado anteriormente, tu única opción es usar una construcción
“if (MiExpresion is null)
then
”.
Firebird 1.0 no tiene COALESCE
. Sin
embargo, puedes usar cuatro UDF's que proveen una buena parte de su
funcionalidad. Estas UDF's residen en la librería fbudf
y son:
iNVL
, para argumentos enteros
i64NVL
, para argumentos enteros
largos
dNVL
, para argumentos de doble
precisión
sNVL
, para argumentos de cadena
Las funciones *NVL
tienen exactamente dos
argumentos. Como COALESCE
, devuelven el primero
argumento si es no-NULL
; en otro caso, devuelven
el segundo. Recuerda por favor, que la librería fbudf
– y por tanto las funciones
*NVL
– sólo están disponibles para
Windows.
Firebird Documentation Index → Guía de NULL en Firebird → Trabajando con NULLs |