jueves, 19 de septiembre de 2013

Consultas complejas en SQL server a través de diseño

Normalmente para crear una consulta solemos escribirla directamente en el Query Analycer de SQL SERVER, pero si se trata de una query compleja, con diversas tablas y JOIN, nuestra SELECT se puede complicar bastante y nos puede hacer perder mucho tiempo.

Para facilitar el trabajo, crear la query de una forma mucho más rápida  y evitar errores de sintaxis, existe una forma muy fácil de escribir querys muy complejas.Sobre el Object Explorer de SQL SERVER, abrimos las vistas y sobre una vista cualquiera, pulsamos el botón derecho del ratón y elegimos modo diseño:

Consultas complejas en SQL server a través de diseño

Hecho esto nos aparece en la pantalla, el diseño de la vista elegida.

Consultas complejas en SQL server a través de diseño

Cada botón de la barra superior, permite ocultar-mostrar un tipo de vista: Esquemática, de Campos, Query de SQL y finalmente muestra de resultados.

Si queremos hacer nuestra propia query compleja podemos usar dichas pantallas para añadir las tablas necesarias en la parte esquemática (la del botón)

Posicionados sobre esta parte de la pantalla, pulsamos botón derecho del ratón y  pulsamos Add Table). Por supuesto como estamos sobre una vista existente lo más normal es que eliminemos las tablas de esa vista, con mucho cuidado de ponerle un nombre nuevo para no modificar la vista existente.

Consultas complejas en SQL server a través de diseño

Elegimos las tablas que necesitemos de la lista y pulsamos Add

Añadir tabla a consulta Sql server

Con lo que las tablas quedan añadidas en modo esquemático

Relaciones entre tablas SQL Server

Sobre el esquema podemos elegir los campos a mostrar de cada tabla pulsando sobre ellos y las relaciones entre los campos arrastrando y soltando los campos que queremos que se relacionen.

Relaciones entre tablas SQL Server

También podremos verificar los campos a mostrar en la pantalla de tipo  

tablas SQL Server
En dicha pantalla podemos escribir directamente el tipo de ordenación deseado

ordenar tablas SQL Server

O las funciones OR y AND

Funciones OR y AND SQL Server

Como ya se ha dicho más arriba, podemos crear nuevas relaciones entre campos de tablas diferentes arrastrando y soltando el ratón entre sendos campos elegidos en cada tabla.

Relaciones SQL Server
Posicionados sobre cualquier relación, con el botón derecho del ratón podemos eliminarla (remove) o elegir el tipo de relación:

Eliminar relaciones SQL Server

Esto nos permitirá crear relaciones sencillas INNER JOIN, o bien en las que prevalezca una de las tablas LEFT OUTER JOIN o RIGHT OUTER JOIN o bien relaciones completas FULL OUTER JOIN.

Elegidas todas las relaciones necesarias y sus tipos, podemos consultar la query generada en el la parte de la pantalla del botón  Botón Query SQL Server


Plan de ejecución textual de SQL server

Para comprobar si las relaciones,  los JOINS y las condiciones WHERE generadas son correctas, basta con pulsar el botón ejecutar  Botón ejecutar SQL Server y en la pantalla de resultados podemos comprobar si estos son los correctos o hay que realizar algún ajuste


Resultado consulta SQL Server

Finalmente, comprobamos que todo es correcto, disponemos de la query por compleja que sea si pulsamos sobrel en botón 



Con lo que podremos copiarla y pegarla donde la necesitemos o incluso almacenarla como una vista pulsando el botón grabar.

Botón grabar consulta SQL Server


miércoles, 18 de septiembre de 2013

Diseñar clases base y clases abstractas

En este artículo, vamos a crear una clase abstracta, una desde la que se debe heredar. En la definición de la clase abstracta, se le determinan los miembros que la clase derivada debe implementar. .NET proporciona varias clases abstractas, diseñadas exclusivamente como clases base para que los desarrolladores las  utilicen para crear nuevas colecciones de clases, también aprenderemos cómo crear miembros de una clase base y de  una clase derivada que tiene el mismo nombre, sin embargo, no se comportan polimórficamente.

Los desarrolladores pueden usar como clases base algunas proporcionadas por el propio entorno .NET diseñadas exclusivamente con este fin para poder crear nuevas clases o colecciones de clases. También es posible que el desarrollador implemente su propia clase base, para ello es necesario determinar los miembros a implementar por las clases derivadas en la clase base.

Clases Abstractas


La abstracción es la característica que nos permite identificar un objeto a través de sus aspectos conceptuales. Las propiedades de los objetos, pueden hacerlos tan distintos que sea difícil reconocer que pertenecen a la misma clase. Por ejemplo dos objetos barco, un crucero y una piragua, su aspecto exterior y tamaño son muy diferentes, sin embargo sabemos que ambos pertenecen a la clase barco.

En el artículo anterior creamos una clase base CPieza y luego derivamos las clases CTorre, CCaballo, CAlfil etc. Como vemos las clases representan el mundo real. Aunque el ajedrez es algo real, es mal ejemplo para explicar las clases abstractas, por que las piezas aunque reales tienen atributos abstractos, así que vamos a pensar  en algo de la vida real.
Por ejemplo una empresa (recordando que las clases deben modelar el mundo real), en dicha empresa hay empleados con diferentes funciones. Por tanto tendremos una clase CEmpleado. Como se ha dicho la empresa tiene distintas funciones para cada empleado, por ejemplo el jefe de fábrica, el jefe de sección, el operario de fresadora, el operario de empaquetadora, etc. La clase CEmpleado deberá definir el comportamiento común de un empleado genérico, a pesar de que nunca existirá un empleado genérico. Utilizaremos la herencia para crear clases derivadas de la clase genérica (abstracta) de empleado.

Otra razón para no crear una clase base, es que se puede crear una instancia y tener la tentación de agregar funcionalidad a la clase base que no es apropiada para derivar clases. Este error es más probable si el diseño se comenzó como una clase normal y corriente CEmpleado y luego derivamos una clase de ella. Supongamos que la empresa comenzó sólo con un tipo de empleado y se creó la clase CEmpleado, cuando la empresa creció, creó  nuevos tipos de empleado y agregó unas clases COperarioM1, COperarioM2 y CJefeSeccion  que se decidió derivar de CEmpleado. Debido a que la nómina de los operarios de máquina iba a tener un incentivo por buen uso de la máquina, al igual que la clase CEmpleado, lo único que se necesitaba era agregar el método Incentivo_Uso a CEmpleado, pero por herencia ahora se debe ofrecer a todos los empleados  ya sean operarios o jefes el incentivo de buen uso de la máquina. La solución a este problema es crear una clase base (abstracta) para COperarioM1, COperarioM2 y CJefeSeccion por ejemplo, CEmpleado_Generico y luego agregar el método Incentivo_Uso1 e IncentivoUso2 respectivamente a las clases COperarioM1 y COperarioM2, de este modo se podrá definir el método para calcular el incentivo, a cada operario en función de su máquina y otros empleados (jefes) no dispondrán de dicho incentivo.

Para evitar la implementación de métodos en las clases base, Visual Basic ofrece la opción de clase base abstracta que permite crear una clase base de la que deriven otras clases pero aunque es posible definir la clase base entera, obliga a implementar los métodos específicos en las clases derivadas. Se pueden declarar referencias a la clase abstracta, pero no se pueden crear instancias de ellas. Como resultado, no se perderá nada del comportamiento polimórfico de las clases derivadas.

Encapsulación


Establece la separación entre el interfaz del objeto y su implementación. Una clase bien encapsulada no debe permitir la modificación directa de  una variable de la clase ni ejecutar métodos que sean internos de la clase.
Un programador podrá utilizar la clase sin necesitar conocer su implementación.

Public.  Será accesible desde todo el código de la clase y de sus clases derivadas, también desde el código de cliente.

Public Function Metodo1

Private. Sólo será accesible desde la propia clase

Private Function Metodo1

Protected. Sólo será accesible desde la propia clase y desde sus clases derivadas

Protected Function Metodo1

Friend.   Será accesible por todo el código de su ensamblado

Friend Function Metodo1

Protected Friend. Será accesible desde el código de su clase y clases derivadas y por todo el código de su ensamblado.

Protected Friend Function Metodo1

Rediseño  de la clase CPieza


La clase CEmpleado_Generico puede ser completamente funcional, y  puede llevar a errores en el programa si alguna vez es  instanciada la clase porque su comportamiento no sería el de una clase COperarioM1 ni una clase CEmpleado. Se tiene que crear la clase CEmpleado_Generico como una clase abstracta.  La clase CEmpleado_Generico tendría una propiedad ID cuyo formato depende del tipo de empleado. Debido a que la propiedad ID depende del tipo de empleado, no hay razón para implementar este método en la clase base y además, no debería implementarse en la clase base. Si se hizo así, la implementación no sería correcta para cualquier tipo de empleado. Usando una propiedad abstracta en la clase base obligamos a implementar este método en las clases derivadas. Volviendo al ejemplo del  ajedrez en este documento, también se agregará el método abstracto Mover  Si este método se implementa en la clase base, no sería válido para ninguna de las clases derivadas.

Se nos puede ocurrir implementar el método
Mover en la  clase base, luego verificamos el tipo de la instancia y posteriormente movemos la pieza dependiendo del tipo que sea. "Esta solución funciona, siempre y cuando sepamos cuales son todas las clases derivadas de la clase base, pero hacer esto limitaría la capacidad de reutilización de la clase base. En general, las clases base no deben contener código que depende de las clases derivadas.

Descripción del diseño usando Lenguaje de Modelado Unificado (UML)


El Lenguaje de Modelado Unificado (UML) es una herramienta gráfica para describir el diseño orientado a objetos. Estas herramientas de desarrollo permiten discutir los diseños con un vocabulario común. También se disminuye la ambigüedad en la especificación. La unidad básica del diagrama de clases es la caja, que representa a la clase:

                                             Lenguaje de Modelado Unificado (UML)



El elemento de clase consta de dos secciones a continuación del nombre, uno para especificar las propiedades y otro para especificar los métodos:

                                     Lenguaje de Modelado Unificado (UML)

El diagrama muestra la clase base abstracta CPieza. El título en cursiva indica que CPieza es una clase abstracta. En UML  se indican los valores por defecto de las listas de propiedades, y especifica las propiedades públicas colocando un signo más delante de ellas.

A continuación, en la parte inferior del cuadro se enumeran los métodos públicos definidos en la clase. UML también indica los parámetros de los métodos y sus valores de retorno. La  palabra “in” indica que el parámetro se pasa por valor. Aquí se muestra el diagrama completo de clases UML.

                             Lenguaje de Modelado Unificado (UML)


UML también muestra las clases derivadas de la relación de herencia mediante una flecha que apunta hacia la clase base. Las clases derivadas heredarán todo de la clase base, por lo que no se muestran los métodos, sólo se muestran si hay  adiciones en las clases derivadas.

El diagrama de clases UML no especifica el comportamiento de la interfaz. Por ejemplo, No se explica cómo deben implementarse las propiedades ni los métodos.


Creando la Clase abstracta


La primera clase que creamos era CPieza, vamos a declararla de nuevo como clase abstracta, para ello basta con hacer.

Public MustInherit Class CPieza

La declaración de las variables y métodos no abstractos, se queda como estaban en el anterior documento, pero las funciones abstractas ya no pueden llevar implementación por lo que quedan del siguiente modo.


Añadir miembros abstractos


'Método padre vacio, se definirá en cada clase hija
Public MustOverride Function Mover(ByVal NuevaPos As String) As Boolean

La declaración en la clase base no se puede implementar porque se debe hacer en   la clase derivada. Al añadir la palabra clave MustOverride, se obliga a que la propiedad o método se definan en cada clase derivada.
Si se declara uno de los miembros de una clase utilizando esta palabra clave, También se debe declarar la clase como abstracta. Los elementos declarados permanecen como lista de tareas hasta  que se implemente. Sin embargo, si se declara una clase como abstractano obliga a dejar vacías las declaraciones de cualquiera de los miembros de la clase abstracta.

Si hay múltiples niveles de herencia hay que aplicar algunas normas:
Supongamos por ejemplo, que se utilice CPieza como una clase base para las clases CTorre y CCaballo. Si se implementa Mover en CPieza, no se está obligado a implementarlo en  CTorre y CCaballo. CTorre y CCaballo pueden heredar la implementación que haya en CPieza.

Si el método en la clase padre se declara MustOverride, se obligará a declararlo en las clases hijas.  En este caso la declaración del método no se pone.

Una Clase Colección


Existe en la biblioteca de clases de  .NET una clase ya creada llamada ArrayList es muy flexible porque se puede añadir cualquier tipo de objeto a la misma. La desventaja de usar la clase ArrayList es que se puede agregar accidentalmente un objeto que no sea del tipo de la clase, es posible que se produzca un error cuando se recupere el objeto de la clase ArrayList.

Una manera razonable de evitar errores en la conversión de tipos es crear una clase que acepte un único tipo de instancia de tipo CPieza y devuelva sólo los casos de instancias de CPieza.
.NET proporciona la clase abstracta collection que se puede utilizar como clase base para las clases colección escritas. La clase  collection sólo permite agregar o quitar un tipo de objeto. Esto significa los errores aparecerán en tiempo de compilación en lugar de en tiempo de ejecución.


Derivar de una clase abstracta de .NET para crear una clase Colección


En la documentación de las clases System.Collections.DictionaryBase dice: "Proporciona la clase base abstracta (MustInherit) de la clase base para una colección con establecimiento inflexible de las claves y valores asociados”.

Añadir el método Añadir


Vamos a crear un array de piezas en la clase CPieza, para ello utilizaremos la clase base predefinida para las colecciones. En la declaración de la clase ponemos:

Public Class CPieza

    Inherits System.Collections.DictionaryBase  'Se usará para crear         un array de piezas.

Después añadimos el procedimiento Añadir que añade una instancia de CPieza a la colección.

Public Sub Añadir(ByVal unaPieza As CPieza)
      Me.Dictionary.Add(unaPieza.Nombre, unaPieza)
End Sub

Ahora nadie va a ser capaz de añadir nada a la colección que no sea una instancia de CPieza Además, la pieza siempre será mostrada con su nombre.

Añadir el método Eliminar


Public Sub Eliminar(ByVal title As CPieza)
        Me.Dictionary.Remove(title)
End Sub

Añadir la propiedad  ExistePieza


Esta propiedad lleva delante la palabra clave Default que significa que cuando llamamos al entrar en la clase CPieza lo primero que se ejecuta es esta propiedad que verifica si la pieza a meter ya existe en la colección.

Default Public ReadOnly Property ExistePieza (ByVal title As String) As CPieza
        Get
            If Me.Dictionary.Contains(title) Then
                Return CType(Me.Dictionary(title), CPieza)
            Else
                Return Nothing
            End If
        End Get
End Property

Si queremos crear un par de funciones en el código cliente para añadir y eliminar objetos de la colección, en el código del Formulario podemos hacer

Private m_Piezas As New CPieza

Public Sub MeterPieza(ByVal nuevaPieza As CPieza)
      m_Piezas.Añadir(nuevaPieza)
End Sub

Public Function SacarPieza(ByVal title As CPieza) As CPieza
      Dim Pieza As CPieza = m_Piezas
      m_Piezas.Eliminar(title)
      Return (Pieza)
End Function
                                      
Y entonces en el Form_load podemos hacer lo siguiente

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

  Dim T As New CTorre
  Dim EnColeccion As CPieza

  T.Nombre = "TD"
  T.Añadir(T)  'añadir una torre directamente a la colección
  MeterPieza(T) 'añadir una torre a través de las funciones cliente

  EnColeccion = T.ExistePieza("TD") 'recupera la torre de la colección

  T.Eliminar(T)  'Elimina la torre directamente de la colección
  SacarPieza(T)  'Elimina la torre a través de las funciones cliente

End Sub

Variaciones en la herencia


Hay otras dos variaciones de la herencia que merecen una mención. Las clases selladas
que permiten impedir la herencia. También pueden impedir que los miembros de la base se comporten polimórficamente.

Clases Selladas


Algunas veces no se debe permitir a los programadores usar una clase como clase base, se puede prevenir esto usando la palabra clave  NotInheritable:

NotInheritable Class NotABaseClass
End Class


Ocultar miembros de clase base


La palabra clave Shadows  indica que aunque un método en la clase derivada tenga el mismo nombre que un método virtual en la clase base, el método de la clase derivada no está destinado a ser el reemplazo del de la clase base del método virtual de la clase. El efecto es que una referencia a la clase  base llama al método base y una referencia a la clase derivada llama al método derivado. La palabra clave Shadows se aplica a todos los métodos del mismo nombre en la clase base.

Class ClaseBase
      Public Sub MetodoBase()
            Console.WriteLine("MetodoBase en Clase base.")
      End Sub
End Class

Class ClaseDerivada
      Inherits ClaseBase

      Public Shadows Sub MetodoBase()
            Console.WriteLine("MetodoBase in clase derivada.")
      End Sub

      Public Shared Sub Main()
            Dim derivado As New ClaseDerivada()
            derivado.MetodoBase()

            Dim base As ClaseBase = derivado
            base.MetodoBase()
      End Sub
End Class

La salida de Main es
MetodoBase en la clase derivada.
MetodoBase en la clase base.

Se debe usar Shadows con precaución, pues los programadores esperan derivar clases preferentemente para actuar polimórficamente.