viernes, 27 de noviembre de 2015

Receta T-SQL No. 3-4: Búsqueda de Valores Desconocidos -NULL- en un Tabla

Índice

1. Introducción
2. Palabras Clave
3. Problema
4. Solución
5. Discusión de la Solución
5.1 NULL
5.2 Operadores relacionales
5.3 Evaluación de expresiones aritméticas y lógicas
5.4 Los operadores IS NULL y IS NOT NULL
5.5 Ejemplos de uso
6. Práctica: Código T-SQL
7. Conclusiones
8. Literatura & Enlaces

1. Introducción

En esta nueva receta T-SQL se explora el mecanismo de búsqueda de valores desconocidos -o NULL- en una tabla. Así mismo, se estudia cómo el motor de base de datos lleva a cabo esta búsqueda. Se estudia, por otro lado, las diferencias entre la función ISNULL y los operadores IS NULL e IS NOT NULL. A través de un plan de ejecución se demuestra el modo en que SQL Server ejecuta una sentencia SQL con el propósito de distinguir el rendimiento entre la función ISNULL y los operadores IS NULL y IS NOT NULL. Algunos ejemplos prácticos demuestran esta forma de proceder del motor de base de datos y que el programador debe tener en cuenta a la hora de componer sus sentencias de búsqueda de valores NULL.

2. Palabras Clave

  • Base de datos
  • Lenguaje de programación
  • NULL
  • Plan de ejecución
  • Sentencia
  • T-SQL

3. Problema

Se requiere implementar un mecanismo óptimo para la búsqueda de valores desconocidos, es decir NULL, en una tabla de una base de datos.

4. Solución

T-SQL provee dos operadores útiles, además de óptimos, para la búsqueda de valores desconocidos. Se trata de los operadores unarios:
  • IS NULL, y 
  • IS NOT NULL

5. Discusión de la Solución

5.1 NULL

Vale insistir que NULL no es un valor distinto a cualquier valor de los tipos de dato disponibles en T-SQL. Sencillamente, NULL, es un valor desconocido o no-existente.

5.2 Operadores relacionales

Los operadores relacionales no deben ser usados para comparar o igualar un valor conocido -un entero, una fecha, un booleano, etc.- con el valor desconocido NULL. Es decir, que expresiones como 
  • WHERE NombreColumna <> NULL
  • WHERE NombreColumna = NULL
no tienen la lógica esperada de un lenguaje de programación como C#, Java, Python. En un lenguaje declarativo como T-SQL no mantiene la misma lógica de evaluación de expresiones booleanas.

5.3 Evaluación de expresiones aritméticas y lógicas

Para afianzar la diferencia NULL respecto a un valor conocido, se ha de considerar preguntas como:
  • ¿Cuál es el resultado de evaluar NULL + 1? ¿NULL?
  • ¿Qué se obtiene de la siguiente expresión aritmética NULL * 5? ¿NULL?
  • ¿Qué se obtiene con NULL = 1¿NULL?
  • ¿Y al comparar NULL <> 1¿NULL?

5.4 Los operadores IS NULL y IS NOT NULL

Los operadores IS NULL y IS NOT NULL ("IS [NOT] NULL", 2015) determinan si una expresión es NULL. La sintaxis de este operador es como sigue:

expresion IS [ NOT ] NULL

Sus argumentos comprende:
  • expresion: un valor literal, variable, valor de columna, retorno de una función, o cualquier otra expresión T-SQL válida.
  • NOT: invierte la expresión lógica con el operador lógico NO.

5.5 Ejemplos de uso

En este primer ejemplo se demuestra el uso incorrecto y correcto de NULL en la sentencia de control CASE WHEN:

DECLARE @valor INT = NULL;

SELECT CASE WHEN @valor = NULL THEN 1
    WHEN @valor <> NULL THEN 2
    WHEN @valor IS NULL THEN 3
    ELSE 4
END;

A la variable @valor se le asigna NULL. Luego, a través de la cláusula de control CASE WHEN se evalúa el valor de esta variable en las expresiones:
  • @valor = NULL
  • @valor <> NULL, y 
  • @valor IS NULL
Solo la última expresión es valida; por lo tanto el valor que se escoge es 3.

Ahora, en un caso más concreto se quiere obtener el listado de 5 personas que no han suministrado su segundo nombre en el registro:

SELECT TOP 5
    FirstName AS 'Primer Nombre', LastName AS 'Apellido', MiddleName AS 'Segundo Nombre'
    FROM Person.Person
    WHERE MiddleName IS NULL;

Al ejecutar este código T-SQL se obtiene:
Uso operador IS NULL
Figura 1. Uso operador IS NULL.

6. Práctica: Código T-SQL

Se aprovechará esta sección práctica para demostrar las diferencias de rendimiento al usar la función ISNULL y el operador IS NULL.

Problema: Obtener los datos -ID de candidato e ID de entidad- de un candidato que está asociado con una entidad.

Solución (usando ISNULL):

SET SHOWPLAN_TEXT ON;
GO

SELECT JobCandidateID AS 'ID Candidato', BusinessEntityID AS 'ID Entidad'
    FROM HumanResources.JobCandidate
    WHERE ISNULL(BusinessEntityID, 1) <> 1;
GO

SET SHOWPLAN_TEXT OFF;

El plan de ejecución resultante es:

  |--Index Scan(OBJECT:([AdventureWorks2012].[HumanResources].[JobCandidate].[IX_JobCandidate_BusinessEntityID]),  WHERE:(isnull([AdventureWorks2012].[HumanResources].[JobCandidate].[BusinessEntityID],(1))<>(1)))

Nótese que el plan de ejecución indica que se ha usado un escaneo -Scan-, es decir de verificar registro por registro el índice asociado a la tabla JobCandidate para realizar la búsqueda valores no NULL.

Solución (usando el operador IS NULL):

SET SHOWPLAN_TEXT ON;
GO

SELECT JobCandidateID AS 'ID Candidato', BusinessEntityID AS 'ID Entidad'
    FROM HumanResources.JobCandidate
    WHERE BusinessEntityID IS NOT NULL;
GO

SET SHOWPLAN_TEXT OFF;

El resultado del plan de ejecución es:

  |--Index Seek(OBJECT:([AdventureWorks2012].[HumanResources].[JobCandidate].[IX_JobCandidate_BusinessEntityID]), SEEK:([AdventureWorks2012].[HumanResources].[JobCandidate].[BusinessEntityID] IsNotNull) ORDERED FORWARD)

Aquí es donde el operador IS NULL destaca por rendimiento: se usa el índice como sistema de búsqueda eficiente para encontrar aquellos valores no NULL de la tabla JobCandidate.

7. Conclusiones

Se ha comprendido como en SQL Server se puede buscar valores NULL usando construcciones óptimas: los operadores IS NULL y IS NOT NULL. A través de ejemplos se demostró que el uso de funciones deteriora el desempeño de búsqueda, debido a que las funciones -ISNULL, por ejemplo- recurren al escaneo total de la tabla objetivo. La próxima receta T-SQL comprenderá cómo remover valores de un agregado.

8. Literatura & Enlaces

Brimhall, J., Dye, D., Gennick, J., Roberts, A., Sheffield, W. (2012). SQL Server 2012 T-SQL Recipes - A Problem-Solucion Approach. United States: Apress.
IS [NOT] NULL (Transact-SQL) (2015, noviembre 27). Recuperado desde: https://msdn.microsoft.com/es-es/library/ms188795(v=sql.120).aspx.


V

No hay comentarios:

Publicar un comentario

Envíe sus comentarios, dudas, sugerencias, críticas. Gracias.