Recursividad con Sql Server

Una función muy interesante de Sql Server es la de poder seleccionar un conjunto de datos de forma recursiva de manera que podemos obtener una serie en estructura de arbol.

Partimos de una tabla que tiene dos campos, llamados clave y padre, el campo clave se relaciona con el padre para formar la estructura en arbol.

El siguiente procedimiento almacenado muestra un ejemplo de como conseguir esto:

ALTER PROCEDURE [dbo].[Usuarios_seguridad_seleccionar]
AS
BEGIN    
    DECLARE @minClave int
    SELECT @minClave = MIN(Clave) FROM dbo.Usuarios_seguridad;
    
    WITH UsuariosAccesos AS
    (
        SELECT top 1 us1.Padre,us1.Clave,us1.Variable,us1.Modulo,us1.Contenido,us1.Acceso,us1.Imagen 
        FROM dbo.Usuarios_seguridad us1 
        WHERE us1.Clave = @minClave
        UNION ALL
        SELECT top 100 percent us2.Padre,us2.Clave,us2.Variable,us2.Modulo,us2.Contenido,us2.Acceso,us2.Imagen 
        FROM dbo.Usuarios_seguridad us2 
        INNER JOIN UsuariosAccesos AS us3 ON us3.Clave = us2.Padre  
        WHERE us2.Clave <> @minClave 
    )
 
    SELECT TOP 100 PERCENT ia.Padre,ia.Clave,ia.Variable,ia.Modulo,ia.Contenido,ia.Acceso,ia.Imagen 
    FROM UsuariosAccesos ia
    ORDER BY padre, clave
END
GO
 
La clausula with debe contener un miembro delimitador, en este caso el formado por la  primera sentencia Sql que hace referencia al valor mínimo (Primer nodo) y el segundo miembro recursivo que hace referencia a la misma tabla definida el la clausula With.
El procedimiento almacenado calcula el valor mínimo del nodo con la clave mas baja, posteriormente va leyendo cada nodo relacionado de forma recursiva ya que en el inner join se relaciona con el conjunto de datos definido en la clausula WiTH, finalmente devuelve el conjunto de datos en un orden determinado, el resultado obtenido es el siguiente:

image

La consulta retorna los datos de forma similar a la estructura de arbol que posteriormente se carga en el tree.

image

Para cargar los datos en el control, podiamos haberlo hecho sin recurrir a la recursividad en Sql Server y hacerlo directamente con el lenguaje de programación en el cliente, pero hay veces que puede ser mas interesante recurrir al servidor en lugar de hacerlo en el cliente, por ejemplo para buscar un dato determinado aprovechando las ventajas de las busquedas en el servidor y devolver su nodo, borrar todos los nodos relacionados o simplemente por descargar la tarea del lado del cliente.

Si quereis mas información sobre la clausula WITH que permite realizar este tipo de consultas podeis encontrala en http://msdn.microsoft.com/en-us/library/ms175972.aspx (Ingles) o http://technet.microsoft.com/es-es/library/ms175972(SQL.90).aspx (Español).

Calidad de código

La calidad de software engloba muchos y diferentes aspectos sobre el desarrollo de aplicaciones, que pasan desde la elección de una buena arquitectura, hasta utilización de diferentes herramientas, la aplicación de diferentes técnicas y metodologías de trabajo. Creo que todavía hoy en día, existe mucha gente reticente a apostar por la calidad de código, debido a que piensan que su coste es mayor que su beneficio.

Cuando empecé a trabajar en equipo, surgieron una serie de problemas de difícil solución, en seguida me di cuenta de que los programadores escribimos código de forma muy diferente que realiza las mismas cosas, generalmente algunos, los más experimentados solían redactar un código mas legible, mejor documentado, necesitaban menos líneas para llegar a la misma solución, ya que sus conocimientos eran mayores, esto originaba muchos problemas cuando tenian que modificar o entender el código de los demás y es aquí cuando empecé a interesarme por las reglas de estilo, fxcop y otras herramientas que de alguna forma nos permitían establecer reglas para que todos pudiéramos por decirlo del alguna forma “entendernos mejor”. Por otra parte en la depuración de las aplicaciones observe que era mucho menos costoso detectar y corregir un error en una fase temprana que hacerlo posteriormente.

Para poder entender mejor el trabajo de los otros programadores comenzamos a aplicar algunas de estas reglas, desde normas de estilo, documentación, desarrollo de pruebas unitarias, aplicación de patrones de diseño, normativas de base de datos y un largo etc. Esto empezó a facilitarnos la compresión y la modificación de programas, en poco tiempo empezamos a tener una visión muy diferente del proyecto, nos aporto más claridad y conocimiento del trabajo de los demás y nos ayudo a detectar gran parte de errores en una fase temprana del desarrollo.

Algunos de los beneficios más importantes que observo son los siguientes:

– La aplicación de patrones de diseño suponen la solución más adecuada para resolver un problema determinado. Esta ha sido elaborada y seleccionada en base al entendimiento y posibles soluciones propuestas y analizadas por mucha gente.

– La adopción de herramientas como fxcop, stylecop, resharper, coderush, refactor y otras, permiten minimizar algunos errores en la fase de desarrollo además de obligar a cumplir ciertas reglas de calidad y estilo, que de no utilizar, provocan si el desarrollador no es un experto, a cometer errores de difícil detección como fugas de memoria, aprovechamiento óptimo de los recursos, localización de código no utilizado, y un largo etc. Por otra parte si todos las adoptan nos habituamos a escribir código de una manera similar, con lo que nos será más fácil comprender el trabajo de los demás. De la información de los errores que nos proporcionan aprendemos a programar mejor, liberando y utilizando recursos adecuadamente, con lo que nuestro conocimiento aumenta. Algunas de estas herramientas cuentan con utilidades para ayudarnos a escribir el código y refactorizar de una forma mucho más rápida.

– El uso de profiles nos permite detectar cuellos de botella y otros problemas que de otra forma serian prácticamente imposible de conocer.

– La utilización de pruebas unitarias y otras técnicas de testeo, nos permiten detectar errores en una fase temprana, si no lo hacemos a tiempo a veces puede implicar que tengamos que modificar más de un módulo relacionado con este, con lo que el coste se incrementa aún más. Como dice la frase, “más vale prevenir que curar”.La ventaja de contar con pruebas unitarias de un módulo que no hemos desarrollado nosotros nos permite entender mejor el comportamiento del programa. La aplicación es más fácil de modificar ya que si alguien altera el programa, por ejemplo cambiando el nombre de un campo de un procedimiento almacenado o alterando alguna función como el cálculo de totales de una factura, detectaríamos el error mucho antes de ponerlo en producción evitando mayores consecuencias.

– Se disminuye la dependencia del equipo de desarrollo: Si el día mañana alguno de los desarrolladores no está o la empresa de desarrollo cierra, será mucho más fácil encontrar a alguien que entienda el código que cumple unas determinadas reglas. Si cada miembro del equipo escribe software de forma diferente esto se hace practicamente imposible. Si otra persona o empresa externa cumple nuestros requisitos de calidad esto permite que pueda comprender y extender la aplicación más fácilmente.

La calidad de código no es opcional, de no aplicarla el coste de nuestros proyectos con seguridad será mayor.

Pero no todo es de color de rosa, utilizar estas herramientas requiere tiempo, formación y sobre todo constancia. Realizar pruebas unitarias además de ser costoso requiere mucha disciplina y un alto nivel de desarrollo, no solamente debemos preocuparnos de tener la máxima cobertura en nuestro código, si no que debemos intentar probar todos los extremos, valores nulos y otros factores que de no realizarse disminuyen los beneficios de estas. De igual forma aprender a utilizar profiles y otras herramientas llevan mucho tiempo en formación y desde luego tienen su coste. No debemos obsesionarnos con realizar pruebas unitarias y cumplir con el 85 % de cobertura en todo nuestro proyecto o cumplir a raja tabla todas las reglas que propone fxcop, resharper, coderush, utilizar reglas de estilo, realizar pruebas de carga, utilizar mock objects para crear independencia con nuestro entorno de datos, utilizar profiles para analizar hasta la más mínima señal de que algo va mal, etc, debemos comenzar poco a poco implantando alguna y habituarnos a utilizarla. Si haceís esto y dedicais un poco de tiempo en aprender a sacarles partido, os puedo asegurar que la mayoría se harán indispensables en vuestro trabajo.

Recuerdo que la primera vez que pusimos en marcha fxcopy en uno de los proyectos aparecieron miles de warnings, os aseguro que fue un autentico coñazo eliminarlos, ya que lo aplicamos en una fase media del desarrollo, nos costó bastante tiempo poner la aplicación en orden, pero aprendimos un motón de cosas sobre programación, algunas que nunca hubiéramos conocido si no llega a ser por este tipo de herramientas. Ahora no podemos vivir sin él y cuando vemos una aplicación que no lo utiliza en seguida nos damos cuenta de los errores que se cometen.

Las ventajas de desarrollar código de calidad son innumerables, se facilita la detección precoz de errores y nos permite anticiparnos y corregirlos antes de poner el sistema en producción evitando tener que rehacer gran parte de las aplicaciones. Estas herramientas nacen con el objetivo de permitirnos mejorar en nuestros desarrollos, no quiere decir que nuestra aplicación vaya a estar libre de fallos, pero si que será mejor, que aprovechara mejor los recursos y por supuesto, que tendrá menos errores, tendremos mayor seguridad a la hora de modificar un programa y reglas de trabajo en equipo que de otra forma serian muy difíciles de controla, se facilita la escritura de código y la detección visual de errores en tiempo de diseño, ahorrando mucho tiempo a la hora de programar y depurar la aplicación.

El esfuerzo que debemos realizar para desarrollar código de calidad es grande, pero marcara la diferencia y en poco tiempo nos permitirá recuperar la inversión con creces, así que animaros, merecerá la pena.