jueves, 22 de noviembre de 2007

Un poquito de SQL

Este es un truquillo que me enseñó hace unos años mi amigo Virgilio para evitar el tostón de andar con condicionales en SQL, en ciertos casos.

Tengo un listado de personas con cuatro parámetros (Nombre, apellido, dirección y teléfono) y quiero buscar por alguno de estos parámetros, por ninguno o por todos. Osea, si meto un nombre que me devuelva todas las personas con ese nombre, y si además le meto la dirección que me devuelva todas las personas con ese nombre y dirección.

¿Qué es lo primero que se le ocurre a un lego en programación SQL como yo? Ale, hacer un condicional y un select por cada uno de los parámetros. Algo como

@nombre
@apellido
@direccion
@telefono

IF @nombre = NULL
BEGIN
Select * from tabla where apellido = @apellido AND dirección = @direccion AND telefono = @telefono
END

Y así por cada uno de los parámetros… y eso sin contar con la tabla auxiliar donde meter los resultados para evitar duplicados, etc. Osea, un porrón de líneas de código.

También he visto hacerlo por medio de código dinámico. Para mi gusto una guarreria que debe dar unos problemas de depuración horrorosos.

@nombre
@apellido
@direccion
@telefono

SET @Select = “select * from table”
SET @Where = ''”
IF NOT @nombre IS NULL SET @Where = @Where + 'nombre=’ + @nombre
IF NOT @apellido IS NULL SET @Where = @Where + 'AND apellido=’ + @apellido
IF NOT @ direccion IS NULL SET @Where = @Where + 'AND direccion =’ + @ direccion
IF NOT @ telefono IS NULL SET @Where = @Where + 'AND telefono =’ + @ telefono

BEGIN
EXEC (@Select + ' WHERE ' + @Where)
END

Y ahora viene la maravilla que me enseño Virgilio, y que ahora comparto en este blog.

@nombre
@apellido
@direccion
@telefono


BEGIN
SELECT * FROM tabla WHERE
(Nombre=@nombre OR @nombre IS NULL)
AND (apellido =@ apellido OR @ apellido IS NULL)
AND (direccion =@ direccion OR @ direccion IS NULL)
AND (telefono =@ telefono OR @ telefono IS NULL)

END

¿A que es complejo de leer?

Pues es muy sencillo. Primero en mi código tengo que asegurarme que el parámetro es uno de dos, o un valor o un NULL. Pero ojo, un NULL de base de datos, osea, un DBNull.value.

¿Qué ocurre cuando, por ejemplo, envío el parámetro @nombre = NULL? El selector de la base de datos lee de forma secuencial desde el principio hasta el final la tabla y va preguntando a cada fila:
-¿Oshes, tu nombre es igual a @nombre? - Y la fila le dice - no, ni parecido-

A lo cual el puntero le vuelve a preguntar a la fila:

¿Oshes el parámetro @nombre es NULL?, a lo cual la fila le dice –pues sí, mira tú-

Y el selector coge la fila y la almacena para ser enviada al finalizar de hacer las mismas preguntas a todas las filas de la tabla.

¿Me entiendess?

Resumen, con estas líneas consigues reducir de forma drástica el código necesario para búsquedas de este estilo.

No hay comentarios: