2014/01/20

NULL VS VACIO

Hola amigos, hace algunos días me encontré con una pregunta sobre comparaciones con NULL y VACIO, les explicaré un poco más con el ejemplo a continuación:
IF OBJECT_ID('tempdb..#tablaTemp' ) IS NOT NULL
       DROP TABLE #tablaTemp

CREATE TABLE #tablaTemp( cve TINYINT IDENTITY(1,1) , valor VARCHAR(10) )

INSERT INTO #tablaTemp( valor )
VALUES( 'UNO') ,( 'DOS' ),( '') ,( 'CUATRO') , ('CINCO') , (NULL),('SIETE'),('OCHO'),(NULL),('DIEZ')
Como pueden observar, en cve con valor 3 he establecido el valor VACIO y en los valores 6 y 9 he establecido NULL
Si aplicamos la siguiente consulta, obtendremos las claves 6 y 9.
SELECT * FROM #tablaTemp WHERE valor IS NULL
Con la siguiente obtendremos solo el valor 3
SELECT * FROM #tablaTemp WHERE valor = ''
Si queremos obtener los valores NULL y VACIO en el mismo recordset, no podemos utilizar el ultimo query dado que no tienen los mismos valores, es decir, el ejemplo de una tabla donde se almacenan los datos de nombre, segundo nombre, apellido paterno y apellido materno, el valor vacio querrá decir que esa persona no tiene un segundo nombre y el valor NULL quiere decir que si tiene pero no lo conocemos, por lo tanto es DESCONOCIDO.

Este es otro ejemplo, como podemos observar NULL no es igual a VACIO y tampoco es DIFERENTE a VACIO, debido a que como lo comentaba anteriormente NULL puede ser cualquier valor, pero no lo conocemos, por lo tanto el motor lo representa así:
DECLARE @vNULL AS NVARCHAR(10) = NULL
DECLARE @vVACIO AS NVARCHAR(10) = ''
DECLARE @vSTRING AS NVARCHAR(10) = 'CADENA'

SELECT
  CASE WHEN @vNULL = @vVACIO THEN 1 ELSE 0 END
, CASE WHEN @vNULL <> @vVACIO THEN 1 ELSE 0 END
, CASE WHEN @vNULL = @vSTRING THEN 1 ELSE 0 END
, CASE WHEN @vNULL <> @vSTRING THEN 1 ELSE 0 END
, CASE WHEN @vVACIO = @vSTRING THEN 1 ELSE 0 END
, CASE WHEN @vVACIO <> @vSTRING THEN 1 ELSE 0 END
Podemos utilizar la función ISNULL, pero tomemos en cuenta que es una carga más para el motor aplicar está función, por ello es necesario identificar claramente el uso de NULL y de VACIO.
DECLARE @vNULL AS NVARCHAR(10) = NULL
DECLARE @vVACIO AS NVARCHAR(10) = ''
DECLARE @vSTRING AS NVARCHAR(10) = 'CADENA'

--USANDO LA FUNCION ISNULL
SELECT
 CASE WHEN ISNULL( @vNULL , '' ) = @vVACIO THEN 1 ELSE 0 END
, CASE WHEN ISNULL( @vNULL , '' ) <> @vVACIO THEN 1 ELSE 0 END
, CASE WHEN ISNULL( @vNULL , '' ) = @vSTRING THEN 1 ELSE 0 END
, CASE WHEN ISNULL( @vNULL , '' ) <> @vSTRING THEN 1 ELSE 0 END
Para aquellos que utilizan NULL o VACIO por que creen que el espacio que utiliza uno u otro es menor:
USE tempdb
DECLARE @c INT
CREATE TABLE #prueba( ide INT IDENTITY(1,1), valor VARCHAR(10) )


SET @c = 1
WHILE @c <1000
BEGIN
       INSERT INTO #prueba( valor ) VALUES( '' )
       SET @c= @c+1
END

SELECT * FROM #prueba

EXEC sp_spaceused #prueba

DROP TABLE #prueba
USE tempdb
DECLARE @c INT
CREATE TABLE #prueba( ide INT IDENTITY(1,1), valor VARCHAR(10) )


SET @c = 1
WHILE @c<1000
BEGIN
       INSERT INTO #prueba( valor ) VALUES( NULL )
       SET @c= @c+1
END

SELECT * FROM #prueba

EXEC sp_spaceused #prueba

DROP TABLE #prueba
SALUDOS!
COMPARTE ESTA INFORMACION SI TE PARECIO INTERESANTE

0 comentarios:

Publicar un comentario