Firebird Documentation Index → Guía de NULL en Firebird → 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.
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 en la conversión de un
NULL
a un valor normal y en otra ocasiones en la
“nulificación” de un valor de entrada válido como
''
(una cadena vacía).
La principal causa de este problema es la llamada “a la
antigua usanza” de la UDF, que no permite pasar un
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
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, cadenas vacías válidas eran graciosamente
convertidas a NULL
.
Las conversiones no deseadas descritas anteriormente normalmente
sólo suceden en UDF's heredadas, pero hay muchas de ellas
(principalmente en ib_udf
).
Además, nada puede evitar que un desarrollador haga lo mismo en
funciones de nuevo estilo. Por tanto, si usas una UDF y no sabes cómo se
comporta respecto a los valores NULL
:
Mira su declaración para ver cómo los valores son pasados y devueltos. Si dice “by descriptor”, debería ser segura (aunque nada se puede decir que sea 100% seguro). En otro caso, sigue el resto de pasos.
Si tienes el código fuente y sabes leer C/C++, inspecciona el código.
Prueba la función con argumentos de entrada
NULL
, y también con valores 0 (para numéricos)
y/o ''
(para cadenas).
Si la función devuelve una conversión
NULL
<-> no-NULL
no
deseada, tienes que trabajar en tu código antes de llamar a la UDF
(mira también Comprobando
si algo es NULL
, también en esta
guía).
Las declaraciones de las UDF's proporcionadas pueden encontrarse
en la carpeta bin/examples
(v.
1.0) o bin/UDF
(v. 1.5 y
superiores) de la instalación de Firebird. Mira en los archivos con
extensión .sql
Para aprender más sobre UDF's, consulta la InterBase 6.0 Developer's Guide (libre en http://www.ibphoenix.com/downloads/60DevGuide.zip), Using Firebird y la Firebird Reference Guide (ambas en CD), o el Firebird Book. El libro y el CD se pueden comprar vía http://www.ibphoenix.com.
Firebird Documentation Index → Guía de NULL en Firebird → Manejo de NULL en UDF's |