libro visual 2010 sql server
TRANSCRIPT
MICROSOFT VISUAL 2010 (ASP.NET) Y
SQL SERVER
MICROSOFT VISUAL 2010 (ASP.NET) Y SQL SERVER
FREDYS A. SIMANCA H. Ingeniero de Sistemas con Énfasis en Telecomunicaciones
Especialista en Redes de Telecomunicaciones Especialista en Multimedia para la Docencia
Magíster en Informática Aplicada a la Educación.
FABIAN BLANCO GARRIDO. Ingeniero de Sistemas
Especialista en Redes de Telecomunicaciones Especialista en Multimedia para la Docencia
Magíster en Informática Aplicada a la Educación. Magíster en Telemática.
Microsoft Visual Studio 2010 (ASP.NET) y SQL Server © Fredys A. Simanca Herrera – Fabián Blanco Garrido Los autores han intentado a lo largo de este libro distinguir las marcas registradas, sin intención de infringir la marca y solo en beneficio del propietario de la misma. Reservados todos los derechos de publicación de este libro. Ninguna parte de este libro puede ser reproducida, grabada en sistemas de almacenamiento o transmitida en ninguna forma ni por cualquier procedimiento, ya sea electrónico, mecánico, por fotocopia, magnético o por otro método, sin el permiso previo o por escrito de los autores del Copyright. DERECHOS RESERVADOS © 2013, primera edición por Fredys A. Simanca Herrera – Fabián Blanco Garrido Bogotá D.C. Abril de 2013.
Agradecimientos
Este trabajo se ha llevado a cabo gracias al aporte de nuestros ex ‐ alumnos y alumnos y en especial a la Universidad Libre, lo cual nos ha llevado a cumplir un sueño de tanto años que por fin hemos culminado y esperamos que sea un aporte a la comunidad como herramienta de apoyo de consulta.
Fredys Alberto Simanca Herrera Fabián Blanco Garrido
CONTENIDO
INTRODUCCIÓN 1. CONCEPTOS PREVIOS 10 1.1 CONTROLES DE SERVIDOR 10 1.2 CONTROLES DE VALIDACIÓN 14 1.3 CONTROLES AJAX 18 1.4 MASTER PAGES 22 1.4.1 ¿Qué son los Master Pages? 23 1.4.2 Definición de un Master Page 24 1.5 WEB SERVICES 27 1.5.1 Características de los Web Services 27 1.5.2 Estructura Interna de los Servicios Web 27 1.5.3 Tipos de Servicios Web 28 1.5.4 Creación de Servicios Web con .NET 29 1.6 CONTROLES DE INICIO DE SESIÓN 35 1.7 CONEXIÓN A UNA BASE DE DATOS DE SQL SERVER DESDE ASP.NET 53 1.7.1 Proyecto Saber Pro 53 1.7.2 Insertar un nuevo registro 60 1.7.3 Uso del GridView para trabajar tablas 61 1.7.4 Pedir confirmación del botón Eliminar en el GridView 64 1.7.5 Insertar botón Nuevo en el GridView 67 1.7.6 Insertar un DropDownList al editar un registro 70 1.7.7 Validación de Usuarios y perfil 71 1.7.8 Envío de Correo desde ASP.NET 74 1.7.9 Módulo Entrenador Pruebas Saber Pro 75 1.7.10 Seleccionar aleatoriamente registros de una tabla 77 1.7.11 Mostrar una imagen de una tabla en una grilla 78 1.7.12 Validar DropDownList insertado dentro de un GridView 81 1.8 Proyecto Banco de Proyectos de Grado 86 1.8.1 Cambiar el MasterPage dinámicamente 91 1.8.2 La función InsertarRegistro 94 1.8.3 Pedir confirmación del botón eliminar en el GridView 89 1.8.4 Módulo Administración de Áreas de Investigación 102 1.8.5 Módulo administración de líneas de investigación 103 1.8.6 Agregar en la grilla un campo de descripción de otra tabla 104 1.8.7 Seleccionar valor de una celda de un GridView 127 1.9 GENERACIÓN DE REPORTES 136 1.10 GENERACIÓN DE GRÁFICOS 138 2. SQL SERVER 160 2.1 INTRODUCCIÓN A SQL 160 2.1.1 ¿Qué es SQL? 160 2.2 LAS CONSULTAS SIMPLES 161 2.2.1 Sintaxis de la SELECT (para consultas simples) 161 2.2.2 Ordenar las filas (ORDER BY) 163
2.2.3 Las cláusulas DISTINCT / ALL 163 2.2.4 La cláusula TOP 164 2.2.5 La cláusula WHERE 164 2.2.5 Condiciones de selección 166 2.2.6 Caracteres Comodines 168 2.3 Las consultas multitablas 168 2.3.1 La unión de tablas 169 2.3.2 La composición de tablas 170 2.3.3 Las funciones de Columna 176 2.3.4 La cláusula GROUP BY 177 2.3.5 La cláusula HAVING 178 2.4 PROCEDIMIENTOS ALMACENADOS 179 2.4.1 Creación Procedimiento Almacenado (Sin Parámetros De Entrada) 180 2.4. 2 Ejecutar Un Procedimiento Almacenado 180 2.4.3 Forma General de un Procedimiento Almacenado 180 2.4.4 Modificación de un Procedimiento Almacenado 181 2.5 TRIGGERS EN TRANSACT SQL 189 2.5.1 Los Desencadenadores DML 189 2.5.2 Los desencadenadores DDL 191 2.5.3 Ejemplo práctico de cómo crear un Triggers en Transact SQL 191 2.6 TRANSACCIONES EN TRANSACT SQL 198 2.6.1 Transacciones implícitas y explicitas 199 2.6.2 Transacciones anidadas 203 2.6.3 Puntos de recuperación (SavePoint) 203 2.6.4 Ejercicio de transacciones 205 2.7 FUNCIONES EN TRANSACT SQL 208 2.7.1 Función Escalar 208 2.7.2 Funciones con valores de tabla de varias instrucciones 210 2.7.3 Funciones con valores de tabla en línea 211 2.8 CURSORES EN TRANSACT SQL 213 2.8.1 Ventajas de los Cursores 213 2.8.2 Estructura de un Cursor 213 2.8.3 Asignación y Asociación de Cursores 226 2.8.4 Procedimientos Almacenados y Cursores 226 2.9 SQL DINÁMICO EN TRANSACT SQL 227 2.10 CERTIFICADOS DIGITALES 231 2.10.1 Firma Digital 235 2.10.2 Utilizar Certificados Digitales Desde .NET 236 2.10.3 Consultar la información del certificado y sus extensiones 239 2.10.4 Encriptación y Desencriptación Utilizando un Certificado 241
INTRODUCCIÓN Hoy en día las capacidades de comunicación, el trabajo en grupo y los conocimientos técnicos, son iniciativas que apoyan a la adaptación de nuestro país a las nuevas tecnologías de aprendizaje, es por ello que se pretende con este material de clase apoyar el desarrollo de éstas capacidades. Este libro se presenta como el resultado de la experiencia que se ha desarrollado en la asignatura Electiva Profesional VI (ASP.NET – SQL Server) en la Universidad Libre y al desarrollo de proyectos en el sector empresarial. Con esta recopilación de apuntes se busca que los estudiantes conozcan los controles más utilizados en ASP.NET, como también realizar las operaciones básicas de las bases de datos: crear, modificar y borrar tablas, actualizar datos, seleccionar datos de una tabla, establecer relaciones entre tablas para la selección de dos o más tablas y realizar consultas avanzadas de bases de datos desde ASP.NET, conocer la conceptualización de los Servicios Web, procedimientos almacenados, funciones con Transact – SQL, Triggers, Transacciones en Transact SQL y Cursores. A medida que se va siguiendo el material se encontraran ejemplos prácticos buscando con ello aclarar los conceptos teóricos aplicando la práctica, y a su vez sean referentes para ser aplicados en otros proyectos de ambientes laborales, tomando como base las situaciones planteadas en los ejercicios que se encuentran en el presente libro.
Los Autores
10
1. CONCEPTOS PREVIOS
1.1 CONTROLES DE SERVIDOR
DropDownList1. Permite a los usuarios realizar una selección en una lista desplegable de selección única.
La lista desplegable puede contener cualquier número de elementos.
Utilice el control DropDownList para crear un control de lista desplegable de selección única. Para
controlar la apariencia del control DropDownList, establezca el valor de las propiedades BorderColor,
BorderStyle y BorderWidth.
Para especificar los elementos que van a figurar en el control DropDownList, coloque un elemento ListItem
por cada entrada entre las etiquetas de apertura y de cierre del control DropDownList.
El control DropDownList también admite el enlace de datos. Para enlazar el control a un origen de datos,
cree primero un origen de datos, como una lista ArrayList, que contenga los elementos que se van a
mostrar en el control. A continuación, utilice el método DataBind para enlazar el origen de datos al control
DropDownList. Utilice las propiedades DataTextField y DataValueField para especificar qué campo del
origen de datos se va a enlazar a las propiedades Text y Value, respectivamente, de cada elemento de lista
del control. Ahora, el control DropDownList mostrará la información del origen de datos. Esta opción la
veremos en funcionamiento cuando utilicemos el control en nuestro aplicativo.
La propiedad que se tiene que tener en cuenta es la SelectedIndex para determinar mediante
programación el índice del elemento seleccionado por el usuario en el control DropDownList. A
continuación, se podrá utilizar el índice para recuperar el elemento seleccionado de la colección Items del
control, la otra propiedad es la propiedad SelectedValue, esta nos determina el valor del elemento
seleccionado.
Ejemplo:
Inserte los controles que observa en la imagen en un Web Forms (TextBox1, Button1 y DropDownList1).
Ingresemos en el botón el código que se observa en la imagen.
11
Ejecute la aplicación (F5) e ingrese valores en el Textbox y de clic en el botón, observe el resultado.
De esta forma se agregan ítems al DropDownList por medio de código, se puede de igual manera agregar
valores de manera manual, para ello, seleccione el Control, de Clic en la pestaña ( ),
seleccione Editar Elementos, y observe la siguiente imagen.
Observe las propiedades Text y Value, estas son las dos propiedades que luego podremos evaluar cuando
se seleccione una opción. Clic en Aceptar.
Si queremos programar los eventos del DropDownList, debemos de activar el Habilitar AutoPostBack.
12
Insertemos un Label1, al frente del control para mostrar el Ítem seleccionado.
El código es el siguiente:
En este caso el mismo valor del SelectedItem es igual al SelectedValue, edite los elementos del Control
nuevamente y cambie la propiedad Value, cuando se traen datos desde una base de datos muchas veces
estas dos propiedades deben de tener valores distintos, supóngase que al usuario se le desea mostrar los
nombres de unos clientes, pero internamente el valor que nos interesa es el número de documento del
cliente, pero como nuestro usuario no se sabe los números de documentos lo que se le debe de mostrar
a él, son los nombres. El siguiente código nos agrega opciones diferentes a text como a value, tiene la
misma funcionalidad cuando se desea hacer con base de datos.
ListBox. El componente ListBox tiene el mismo comportamiento que el control DropDownList.
FileUpload. Crea un control <input type=file> (que por lo general se muestra como un control de cuadro
de texto y un botón de examinar) que permite a los usuarios seleccionar un archivo para cargarlo en el
servidor.
Ejemplo: En el ejemplo siguiente se muestra cómo crear un control FileUpload que guarda los archivos en
una ruta de acceso especificada en código. Se llama al método SaveAs para guardar el archivo en el
servidor en la ruta de acceso especificada. La aplicación ASP.NET que contiene el ejemplo debe tener
derechos de escritura en el directorio especificado del servidor. Se puede conceder explícitamente
13
derecho de escritura a la cuenta en que se está ejecutando la aplicación, en el directorio en que se van a
guardar los archivos cargados. Si se prefiere, se puede aumentar el nivel de confianza que se concede a la
aplicación ASP.NET.
Diseñe una vista como la de la imagen.
Seleccione el Botón (UpLoad) y en el código ingrese el siguiente:
Ejecute la aplicación, el resultado debe ser como se observa en la imagen.
Hagamos ahora unas pequeñas modificaciones para tener información sobre el archivo. Modifique el
código y déjelo como se ve en la imagen.
14
Ejecute y observe los cambios.
1.2 CONTROLES DE VALIDACIÓN
Se usan para validar los valores que se especifican en otros controles de la página. Los controles de
validación realizan la validación en el cliente, el servidor o ambos, según las capacidades del explorador en
el que se muestra la página. Los controles de validación proporcionan las ventajas siguientes:
Puede asociar uno o varios controles de validación a cada control que desee validar.
La validación se realiza cuando se envía el formulario de la página.
Puede especificar mediante programación si debería realizarse la validación, lo que resulta de
utilidad si desea proporcionar un botón de cancelación para que el usuario pueda salir sin tener
que rellenar con datos válidos todos los campos.
Los controles de validación detectan automáticamente si se debe realizar la validación en el cliente o en
el servidor.
15
RequiredFieldValidator. El control RequiredFieldValidator se utiliza para convertir un control de entrada
en un campo obligatorio. El control de entrada no supera la validación si el valor que contiene no cambia
con respecto al valor inicial cuando se realizó la validación. Esto impide que el usuario deje el control de
entrada asociado sin modificar. De manera predeterminada, el valor inicial es una cadena vacía (""), lo que
indica que se debe especificar un valor en el control de entrada para que supere la validación.
CompareValidator . El control CompareValidator permite comparar el valor especificado por el usuario
en un control de entrada (por ejemplo, un control TextBox) con el valor especificado en otro control de
entrada o con un valor constante. También se puede usar el control CompareValidator para determinar si
el valor especificado en un control de entrada se puede convertir al tipo de datos especificado por la
propiedad Type.
Especifique el control de entrada que desee validar estableciendo la propiedad ControlToValidate. Si
desea comparar un control de entrada específico con otro control de entrada, establezca la propiedad
ControlToCompare en el nombre del control que desee comparar.
En lugar de comparar el valor de un control de entrada con otro control de entrada, se puede comparar el
valor de un control de entrada con un valor constante. Especifique el valor constante que va a comparar
estableciendo la propiedad ValueToCompare.
CustomValidator. El control CustomValidator permite crear un control de validación con lógica de
validación personalizada. Por ejemplo, se puede crear un control de validación que compruebe si el valor
especificado en un cuadro de texto es un número par.
Los controles de validación siempre realizan la comprobación de validación en el servidor. También tienen
una implementación completa en el cliente que permite a los exploradores compatibles con DHTML (como
Microsoft Internet Explorer 4.0 ó posterior) realizar la validación en el cliente. La validación en el cliente
mejora el proceso de validación ya que se comprueban los datos proporcionados por el usuario antes de
enviarlos al servidor. De este modo se pueden detectar los errores en el cliente antes de enviar el
formulario y se evita la acción de ida y vuelta de la información necesaria para la validación en el servidor.
Para crear una función de validación de servidor, proporcione un controlador para el evento
ServerValidate que realiza la validación. Se puede obtener acceso a la cadena del control de entrada que
se va a validar utilizando la propiedad Value del objeto ServerValidateEventArgs que se pasa al
controlador de eventos como parámetro. El resultado de la validación se almacena después en la
propiedad IsValid del objeto ServerValidateEventArgs.
Para crear una función de validación en el cliente, agregue primero la función de validación en el servidor
que se ha descrito anteriormente. A continuación, agregue a la página .aspx la función de script de
validación en el cliente.
Si utiliza Visual Basic, la función debe tener el siguiente formato:
16
Sub ValidationFunctionName (source, arguments)
Si utiliza JScript, la función deberá tener la siguiente forma:
Function ValidationFunctionName (source, arguments)
Utilice la propiedad ClientValidationFunction para especificar el nombre de la función de script de
validación de cliente que está asociada al control CustomValidator. Como la función de script se ejecuta
en el cliente, debe estar en un lenguaje que el explorador de destino admita, como Visual Basic o JScript.
Al igual que en el caso de la validación en el servidor, la propiedad Value del parámetro arguments obtiene
acceso al valor que se va a validar. Para devolver el resultado de la validación, establezca la propiedad
IsValid del parámetro arguments.
RangeValidator. El control RangeValidator permite comprobar si la entrada de un usuario se encuentra
entre un límite inferior y un límite superior especificados. Se pueden comprobar intervalos entre parejas
de números, caracteres alfabéticos y fechas. Los límites se expresan como constantes.
Utilice la propiedad ControlToValidate para especificar el control de entrada que se va a validar. Las
propiedades MinimumValue y MaximumValue especifican los valores mínimo y máximo del intervalo
válido, respectivamente.
La propiedad Type se utiliza para especificar el tipo de datos de los valores que se van a comparar. Los
valores que se van a comparar se convierten a este tipo de datos antes de realizarse cualquier
comparación.
RegularExpressionValidator. El control RegularExpressionValidator se utiliza para determinar si el valor
de un control de entrada coincide con un patrón definido por una expresión regular. Este tipo de validación
permite comprobar secuencias de caracteres previsibles, como las de los números de la seguridad social,
las direcciones de correo electrónico, los números de teléfono y los códigos postales, entre otras.
ValidationSummary. El control ValidationSummary permite resumir los mensajes de error de todos los
controles de validación de una página Web en una sola ubicación. El resumen puede aparecer en forma
de lista, lista con viñetas o un único párrafo, en función del valor de la propiedad DisplayMode. El mensaje
de error que se muestra en el control ValidationSummary para cada control de validación de la página
viene especificado por la propiedad ErrorMessage de cada control de validación. Si no está establecida la
propiedad ErrorMessage del control de validación, no se mostrará ningún mensaje de error en el control
ValidationSummary correspondiente a dicho control de validación. También se puede especificar un título
personalizado en la sección de encabezado del control ValidationSummary estableciendo la propiedad
HeaderText.
Vamos a ver entonces un ejemplo de cómo funcionan los controles de validación.
Descargue de internet o utilice otro medio para crear una hoja de estilo (css).
17
Copie el archivo css a la raíz de su sitio web, para adjuntar la hoja de estilos a su página, vaya al menú
contextual a Formato Adjuntar hoja de estilos.
Seleccione la hoja de estilo, luego de clic en Aceptar. Después de haber adjuntado la hoja de estilo hagamos
el siguiente diseño:
Ahora en vista diseño, vamos a arrastrar los siguientes controles de Validación, tal y como se puede
observar en la figura.
Vamos a usar los siguientes controles de validación: RequiredFieldValidator, RangeValidator,
RegularExpresionValidator, Compare Validator y por último ValidationSumary.
RegularExpresionValidator
ControlToValidator El Control que quieres validar, en el primer caso será el de email y el de fecha de nacimiento.
ErrorMessage El mensaje de error que se quiere mostrar cuando se presenta un error.
ValidationExpression Seleccione el formato que desea, para el caso de fecha debe buscar en internet la expresión regular para validar la fecha.
ControlToValidator Seleccione el control el cual quiere validar
ErrorMessage El mensaje que se quiere mostrar cuando se ha presentado un error.
RangeValidator Maximun Value Valor máximo que quiere para el rango
Minimun Value Valor mínimo que quiere para el rango, supongamos que solamente aceptamos personas
18
entre 18 y 25 años.
CompareValidator ControlToValidate El control que queremos validar, en este caso es el password.
ControlToCompare El control que queremos comparar, en este caso será el de Reingrese Password.
ErrorMessage El mensaje de error que se quiere mostrar cuando se presenta un error.
RequiredFieldValidator ControlToValidator Seleccione el control el cual quiere validar
ErrorMessage El mensaje que se quiere mostrar cuando se ha presentado un error.
En el control ValidatorSummary no hay necesidad de estipular nada, ya que lo que hace es sacar un
resumen de todos los errores presentados.
Al final debe quedar un diseño como el que se puede observar a continuación.
Ejecute la aplicación y pruebe los resultados.
1.3 CONTROLES AJAX
Visual Studio 2010 y ASP.NET 3.5 permite el diseño y desarrollo de aplicaciones con soporte AJAX.
AJAX son las siglas de Asynchronous JavaScript And XML, o lo que es lo mismo, JavaScript y XML asíncrono,
que en otras palabras, es la capacidad de las aplicaciones Web de establecer un camino de comunicación
asíncrono con el servidor y en segundo plano, para nuestras aplicaciones web.
En realidad, esta técnica tiene mucha importancia con aspectos como SOA (Service Oriented Architecture)
y RIA (Rich Internet Applications).
Aunque no debe haber problemas en el uso de AJAX ya que la mayoría de los navegadores Web lo
soportan, hay que tener en cuenta que existen navegadores Web que no soportan AJAX.
Para crear aplicaciones AJAX en aplicaciones Web con Visual Studio 2010, disponemos de diferentes
objetos que encontraremos dentro del Cuadro de herramientas tal y como se indica en la siguiente imagen:
19
Atendiendo al Cuadro de herramientas, encontramos diferentes objetos
AJAX, como son el objeto ScriptManager, ScriptManagerProxy, Timer,
UpdatePanel y UpdateProgress.
A continuación se expone un ejemplo sencillo del uso de AJAX en
aplicaciones Web.
Partimos de una aplicación Web ASP.NET 3.5 dentro de la cuál
insertaremos dos controles Label y un control Button.
Los nombres de los controles Label son HoraActual y Mensaje. El objetivo
es mostrar en HoraActual la hora actual del sistema, y en Mensaje un
mensaje de texto que nos servirá para indicar que el código pasa por
donde queremos.
Nuestra aplicación Web en la fase de diseño tendrá un aspecto similar al
que se indica en la siguiente imagen:
A continuación, indicaremos el código de nuestra aplicación Web:
20
Este ejemplo, mostrará una determinada información la primera vez que se ejecuta nuestra aplicación y
mostrará la siguiente información:
Si pulsamos el botón, la aplicación realizará un refresco de toda la aplicación Web y ejecutará un camino
de ida y vuelta refrescando todos los objetos de la aplicación. El resultado una vez ejecutado el control
Button es el siguiente:
En este proceso no obstante, no hemos utilizado AJAX aún.
Como vemos, este es el mecanismo tradicional de ejecutar aplicaciones Web, con caminos de ida y vuelta
y refresco de toda la página web completa.
Imaginemos entonces que tenemos varias fuentes de datos asociadas a nuestra página Web y que cada
vez que refrescamos, se vuelven a lanzar todas las acciones de consulta sobre las bases de datos.
En la red se produciría un gran consumo de ancho de banda, y además, penalizaríamos seguramente al
servidor Web.
La idea de AJAX es la de refrescar únicamente aquella información que queremos refrescar.
Por lo tanto, basándonos en el ejemplo que hemos desarrollado, vamos a valernos de los controles AJAX
de Visual Studio 2010 y vamos a crear una aplicación que refresque únicamente aquella información que
queremos refrescar, y no toda la página Web.
Para hacer esto, vamos a insertar primero un control ScriptManager, y posteriormente un control
UpdatePanel. Estos dos controles están dentro del grupo de controles de AJAX.
Una vez hecho esto, insertaremos los controles Button y Label de nombre Mensaje en el control
UpdatePanel.
Nuestra aplicación Web quedará en el entorno de diseño tal y como se indica a continuación:
21
Como el código de nuestra aplicación es el mismo, a continuación ejecutaremos nuestra aplicación Web:
Pulsaremos el control Button de nuestra aplicación y observaremos el resultado obtenido, que será similar
al que se indica en la siguiente imagen:
22
Atendiendo a los resultados, podemos deducir que mientras en el primer caso en el que no usábamos
AJAX, el resultado de la página web era un camino de ida y vuelta refrescando toda la página web, en el
uso de AJAX ese camino de ida y vuelta se ha reducido únicamente a aquellos controles u objetos que
hemos colocado dentro del control UpdatePanel.
Este control actúa como repositorio contenedor de aquellos controles que queremos actualizar,
permitiendo que el resto de la aplicación no quede afectada por esta actualización.
Pruebe por ejemplo colocando un textbox por fuera del control UpdatePanel para que note mejor como
la página no se refresca al momento de dar clic sobre el botón.
1.4 MASTER PAGES
Lo más habitual cuando se crea una aplicación o un sitio Web es que las páginas que lo conforman sean
todas bastante parecidas o al menos que existan varios grupos de páginas similares que sólo varían ciertos
contenidos entre ellas. Por ejemplo, puede haber una categoría de páginas para mostrar artículos en el
que todas son iguales excepto por el contenido del propio artículo en su parte central, mientras que en
otra zona de la aplicación el diseño es completamente diferente pero sus páginas se parecen todas entre
sí.
Por ejemplo, la siguiente figura muestra capturas de dos páginas pertenecientes al portal MSDN:
23
Ejemplo de
dos páginas similares en MSDN
Ambas páginas difieren únicamente en el contenido y los menús que muestran en el lateral (los banners
del lateral son rotativos), y conservan una estática y una serie de elementos que permanecen constantes
en todas las páginas del sitio.
Tradicionalmente para conseguir esta similitud entre páginas había que crearlas individualmente o recurrir
a artificios propios como por ejemplo el de utilizar archivos de inclusión para renderizar ciertas partes de
las páginas desde un mismo origen en disco. Aún en este último caso la capacidad de modificación era
limitada y normalmente se reducía a las cabeceras y pies de las páginas y poco más. En el primero de los
casos (retocar una a una) cualquier cambio estético de un sitio medianamente grande era poco menos que
una locura de realizar.
A partir de ASP.NET 2.0 se ofrece una nueva característica destinada a paliar esta tradicional carencia y
permite definir páginas cuyo aspecto y funcionalidad deriva de unas páginas especiales comunes llamadas
Páginas principales o Master Pages.
1.4.1 ¿Qué son las Master Pages?
Una Master Page proporciona una forma de definir una estructura e interfaz común para un grupo de
páginas pertenecientes a un mismo sitio Web. Esta estructura común se almacena en un único archivo
independiente. Ello facilita mucho su mantenimiento puesto que, para actualizar todas las páginas que lo
utilizan, basta con editar dicho archivo.
24
Una MP es en realidad como una página ASPX normal que contiene código, elementos HTML y controles
Web de servidor. Sin embargo posee una extensión diferente (.master) y utilizan una directiva <% @
master %> en lugar de una directiva <% @ page %>. Por lo demás se pueden considerar prácticamente
equivalentes. Esto es importante porque significa que ya sabemos todo lo necesario para crearlas.
Una página ASPX normal puede derivar su estructura a partir de una MP simplemente añadiendo un
atributo MasterPageFile a su directiva de página, así:
Que indica el archivo de página principal que se utilizará para su estructura.
1.4.2 Definición de una Máster Page
Para agregar una Máster Page a nuestro proyecto sólo hay que elegir el icono Página Principal en el diálogo
de agregar nueva referencia de cualquier carpeta del mismo:
Al abrir una MP aparece un diseñador idéntico al de una página ASPX normal. Podemos arrastrar sobre su
superficie cualquier control así como editar su HTML de la manera usual. También lleva un archivo de
código asociado en el que se puede responder a sus diversos eventos. La única diferencia apreciable a
simple vista respecto a una página normal es que contiene por defecto un control de tipo
ContentPlaceHolder. La sintaxis de este control es análoga a la siguiente:
<asp:ContentPlaceHolder id="head" runat="server"> </asp:ContentPlaceHolder>
25
Su única propiedad interesante es precisamente su identificador ya que este tipo de control se utiliza para
marcar las posiciones en las que irán los diferentes contenidos de las páginas derivadas dentro de la
plantilla de estructura que es una Master Page.
De este modo, cuando una página normal derive de una MP, sólo se podrá introducir código dentro de las
zonas definidas por estos comodines de contenido.
Cuando añadimos una nueva página ASPX a nuestro proyecto y existe al menos una Master Page, podemos
marcar una opción para que, antes de crearla, nos permita seleccionar de qué MP derivará.
Para ello agregue una nueva página, como se muestra en la imagen.
Esto nos evita tener que escribir el atributo MasterPageFile manualmente.
Al editar una página que deriva de una Master Page aparece el aspecto y estructura de la página principal
en el diseñador, pero sólo se pueden tocar las partes correspondientes a los comodines de contenido.
Diseñemos ahora la página master. Puede usar como guía la imagen que se ve en la siguiente figura.
En vista web se debe de ver así:
26
En la página master cambie el nombre del ContentPlaceHolder:
<asp:ContentPlaceHolder id="Detalles" runat="server"> </asp:ContentPlaceHolder>
Igualmente en la PaginaHija.aspx modifique tambien la siguiente línea:
<asp:Content ID="Content1" ContentPlaceHolderID="Detalles" Runat="Server"> </asp:Content>
Ahora vayamos a la PaginaHija.aspx, debe ya aparecer algo como esto:
Escribe o diseña algo dentro de la etiqueta Detalles, luego presiona F5 para ver el resultado de la página.
De esta manera todas nuestras páginas pueden tener el mismo diseño sin necesidad que tengamos que
repetir el diseño en cada una de ellas.
Observe la siguiente imagen para ver los resultados.
27
1.5 WEB SERVICES
Los servicios web pretenden dar un paso más en el desarrollo de aplicaciones para la web, ya que su objetivo es que éstas puedan ser utilizadas por otros programas capaces de procesar las respuestas con otro fin que no sea el de la presentación de información en pantalla, permitiendo además automatizar ciertos procesos en la web al posibilitar transacciones de datos sin intervención de un usuario. Un servicio web es un componente de software que expone un conjunto de operaciones en la Web (métodos), que pueden ser utilizados desde otros programas.
1.5.1 Características de los Servicios Web
Los servicios web poseen una serie de características que los hacen preferibles a estas tecnologías. Entre ellas se pueden destacar:
Utilización de estándares existentes. La base de la arquitectura de servicios web la constituye el protocolo HTTP y el estándar XML. La comunicación cliente – servicio Web se lleva a cabo mediante el intercambio de documentos XML entre ambos. Utilizando HTTP como protocolo de comunicación.
Web Service
Figura1. Acceso a un servicio web desde un cliente
Independencia de la plataforma. La utilización de XML como formato de intercambio de información entre el cliente y el servicio web permite que la comunicación entre ambos pueda realizarse independientemente de la tecnología o lenguaje con el que tanto uno como otro estén implementados, así como la plataforma en la que se ejecuten.
Nuevos estándares abiertos. HTTP y XML constituyen la base principal de los servicios web. Se han desarrollado una serie de tecnologías que permiten estandarizar operaciones como la descripción o la publicación de un servicio web.
1.5.2 Estructura Interna de los Servicios Web
La estructura y la complejidad de un servicio web dependen de las funciones a realizar y del tipo de servicio que se trate. En cualquier caso se pueden distinguir dos componentes básicos:
Request (XML)
Response
28
Componentes software. Se trata de componentes de código reutilizable que implementan la funcionalidad del servicio, sus métodos pueden incluir acceso a diferentes fuentes de datos. La funcionalidad que proporcionan puede ser compartida por el resto de módulos que forman parte de la aplicación web. Estos componentes pueden estar implementados con cualquier tecnología software; en este caso de .NET, esta funcionalidad estaría implementada mediante clases independientes compiladas en un ensamblador dll.
Servidor SOAP. Hace de interfaz entre el cliente y el componente que implementa el servicio. La comunicación entre el cliente y el servicio web se realiza vía XML, utilizando un protocolo de codificación conocido como SOAP. Así que por un lado, este módulo debe encargarse de decodificar las peticiones SOAP que llegan desde el cliente e invocar a los métodos del componente, mientras que por otro lado, debe codificar los resultados devueltos por el componente en mensaje SOAP y enviarlos al cliente. En .NET esta labor se llevaría a cabo mediante páginas aspx dentro de una aplicación ASP.NET
Petición SOAP
Respuesta SOAP
Servidor
Figura 2. Servicio web con .NET
1.5.3 Tipos de Servicios Web
En función de cómo va a ser procesada la información por un servicio web, se pueden dividir estos en dos categorías:
Servicios web orientados a método Se basan en una interacción de tipo Invocación Remota a Método (RPC), donde el documento XML de petición del servicio web representa la llamada a un método o procedimiento con sus respectivos parámetros de entrada, mientras que el documento XML generado como repuesta representa el valor devuelto por dicho método. Es el caso más sencillo de servicio web y el más utilizado, donde cliente y servicio se comunican de forma asíncrona.
Servicios web orientados a documento El documento XML enviado por el cliente al servicio web es procesado por este en su totalidad. Este proceso se lleva a cabo de forma asíncrona y el mismo puede implicar llamadas a diferentes métodos y procedimientos en los componentes del servidor. La llamada de este tipo de servicios web se realiza de forma asíncrona, lo que significa que el cliente puede continuar su ejecución mientras el servicio web procesa el documento.
Servicio web
ASP.NET
ensamblad
29
1.5.4 Creación de Servicios Web con .NET
Para crear un servicio web vamos a Archivo ‐> Nuevo Sitio Web Luego en la ventana siguiente seleccionamos las opciones que se ven en la imagen.
Clic en Aceptar. Por defecto crea un método llamado HelloWorld
Vamos a crear nuestro propio método, el método que se va hacer de ejemplo será el devolver un vector con n número de registros dependiendo de un filtro. Para ello necesitamos la clase que nos conecta a la base de datos en el servicio web.
Selecciona el
FrameWord 3.5
Selecciona Servicio Web
ASP.NET
30
Volvemos al servicio web y creamos la función que nos interesa.
Esta es la tabla de la cual sacaremos los registros aleatorios.
31
Luego ejecutamos la aplicación para ello presionamos Ctrl + F5
Luego en el navegador podemos observar que el servicio web se está ejecutando
Si queremos probar el Servicio Web, de clic sobre el procedimiento e ingrese los datos.
32
Clic en Invocar y el resultado sería:
En este caso, se debe de tener en la tabla un buen número de registros, si se quiere ingresar parámetros
mayores. Vamos ahora a elaborar un proyecto web del cual consumiremos el servicio web.
Después de crear el sitio web, vamos a Sitio Web Agregar Referencia Web
33
Nos mostrara una ventana como la siguiente, en URL copie la ruta del servicio web que está en ejecución.
Clic en el botón Continuar, ingrese un nombre de Referencia y clic en Agregar Referencia.
El resultado será:
34
Ahora vamos a consumir el servicio web, para ello en el archivo Default.aspx, diseñemos una vista como
la siguiente.
Seleccionamos el botón Traer Preguntas e ingresamos el siguiente código.
35
Ejecute la aplicación, ingrese los datos y observe el resultado.
1.6 CONTROLES DE INICIO DE SESIÓN
1. ChangePassword: Permite a los usuarios cambiar la contraseña. El usuario debe proporcionar primero
la contraseña original y, a continuación, crear y confirmar la nueva contraseña. Si la contraseña original
es correcta, la contraseña de usuario se cambia a la nueva contraseña. El control también permite
enviar un mensaje de correo electrónico acerca de la nueva contraseña.
2. CreateUserWizard: Permite crear un asistente para la creación de nuevo usuario donde se puede
capturar la información necesaria para tal fin. De hecho, se requiere información, asimismo, de la
contraseña del usuario nuevo grupo, dirección de correo electrónico, la pregunta de seguridad y
respuesta.
3. Login: Muestra una interfaz de usuario para la autenticación de usuarios. El control Login contiene
cuadros de texto para el nombre de usuario y la contraseña y una casilla de verificación que permite a
los usuarios indicar si desean que el servidor almacene su identidad mediante la suscripción de
ASP.NET y que los autentique automáticamente la próxima vez que visiten el sitio.
4. LoginName: Permite mostrar el nombre de inicio de sesión de un usuario si este ha iniciado la sesión
mediante la suscripción de ASP.NET. Por el contrario, si el sitio utiliza la Autenticación de Windows
integrada, el control muestra el nombre de cuenta de Windows del usuario.
5. LoginStatus: Este control muestra un vínculo de inicio de sesión para los usuarios que no están
autenticados y un vínculo de cierre de sesión para los que están autenticados. El vínculo de inicio de
sesión lleva al usuario a una página de inicio de sesión. El vínculo de cierre de sesión restablece la
identidad del usuario actual y lo convierte en un usuario anónimo.
6. LoginView: Permite mostrar información diferente a los usuarios anónimos y a los que han iniciado
una sesión. El control muestra una de las dos plantillas: AnonymousTemplate o LoggedInTemplate.
En las plantillas, puede agregar marcado y controles que muestren información apropiada para
usuarios anónimos y usuarios autenticados, respectivamente.
36
7. PasswordRecovery: Permite recuperar las contraseñas de usuario basándose en la dirección de correo
electrónico que se usó al crear la cuenta. El control PasswordRecovery envía al usuario un mensaje de
correo electrónico con la contraseña.
Creamos un sitio nuevo
Y agregamos dos Web Form uno con el nombre de Login y otro create account
37
Agregamos un Master Page
Agregamos un Web Form con el nombre de home y seleccionamos el Master Page y otro Default2.
38
39
Vamos al formulario login y agregamos un control LoginView.
40
Agregamos junto al LoginView el control Login
41
En autoform seleccionamos un estilo
Vamos a propiedades a la opción DestinationPageUrl seleccionamos home
42
43
Vamos al administrador del sitio, seguridad, asistente de configuración, vamos al paso dos seleccionar
método de acceso (desde internet) y finalizar
Abrimos create account seleccionamos el control createUserWizard, auto format, después vamos a
propiedades opción DestinationPageUrl seleccionamos Home
44
45
46
Ahora en el Master Page seleccionamos los controles LoginName y LoginStatus
En LoginStatus vamos a propiedades a LogoutAction y seleccionamos RedirectToLoginPaste y en LogoutPageUrl seleccionamos Login
47
Abrimos home.aspx e insertamos un LoginName.
Abrimos ahora el Default2.aspx, e insertamos igualmente un LoginName
Abrimos el Login.aspx agregamos un HyperLink en las propiedades modificamos Text: (Register) y en
navigateUrl seleccionamos Create acount.aspx
48
En el home.aspx agregamos un HyperLink en las propiedades modificamos Text: (Opciones) y navigateUrl
seleccionamos default2.aspx
49
Corremos nuestra aplicación para verificar si podemos registrar.
Intente loguearse con
cualquier usuario
Debe salir un mensaje de error,
como el que se observa en la
imagen, de clic en Register
Ingrese los datos del usuario a registrar y de
clic en Crear Usuario
En la propiedad
navigateURL, seleccione
Default2.aspx
50
Ahora vamos a agregar un nuevo formulario para cambiar la contraseña con el nombre
Changepassword.aspx, tenga presente seleccionar la página maestra.
En Change Password.aspx seleccionamos el control ChangePassword.
En las propiedades del ChangePassword, puede modificar el formato de vista, si así lo desea.
Listo, ahora podrá loguearse con el usuario
que acaba de crear.
51
Nos dirigimos a Default2.aspx y agregamos un HyperLink en las propiedades modificamos Text: (Cambiar
Contraseña) y en la propiedad navigateUrl, seleccionamos la página Change Pasword.aspx
Creamos un nuevo Web Form lo llamamos Password Recovery.aspx
En él agregamos el control PasswordRecovery, cambie el formato si lo desea.
52
Ahora en login.aspx agregamos un HyperLink en las propiedades modificamos Text: (Olvide mi
contraseña) y en la propiedad navigateUrl, seleccione la página Password recovery.aspx
Ejecutamos la aplicación y observamos los resultados.
53
1.7 CONEXIÓN A UNA BASE DE DATOS DE SQL SERVER DESDE ASP.NET
1.7.1 Proyecto SaberPro Cree un proyecto web (usaremos código C#), luego de crear el proyecto agregue una clase, observe la imagen.
Después de crear la clase, ingrese el siguiente código.
Esta función es parar trabajar con la tabla Usuarios, se puede usar la misma para trabajar con diferentes tablas, todo depende de las necesidades que se tenga en el formulario que se está trabajando.
54
Agregar ahora un formulario, para trabajar la tabla llamada TbUsuarios, en la imagen se puede observar el diseño de la tabla.
Agregamos el formulario (frmregistro.aspx), tenga presente seleccionar la opción que dice Seleccione página maestra.
Tenga presente que al momento de crear el proyecto, se debió tener en cuenta, primero crear el proyecto vacío, segundo crear una página maestra para el sitio web.
55
Diseñar en el Web Forms, el formulario de registro de usuarios, ver la imagen siguiente.
Nombre los elementos de la siguiente manera:
TxtDocumento
TxtNombres
TxtApellidos
CmbUniversidad
TxtTelefonoFijo
TxtTelefonoCelular
TxtCorreo
TxtLogin
TxtPassword
CmbPerfil Vamos ahora listar en el CmbUniversidades, las universidades que se encuentran registradas en la base de datos.
56
Seleccione el combo, clic en la pestaña de la derecha y Elegir origen de datos.
En la pestaña seleccione <Nuevo Origen de Datos>
57
Clic en el Botón Nueva Conexión
Seleccionar Microsoft SQL
Server y clic en Continuar
Ingresar el nombre del servidor y
seleccionar la base de datos y clic en
Aceptar
58
Clic en el botón Siguiente
Clic en el botón Siguiente
Seleccionamos la tabla de
nuestro interés, en este caso
TbUniversidades y clic en el
botón Siguiente.
59
Clic en el botón Siguiente
Clic en el botón Aceptar, y esta
sería la vista del formulario.
60
Ahora procederemos a configurar las opciones del CmbPerfil¸ seleccione el combo, clic en la pestaña de la derecha y clic en Editar Elementos, agregue tres opciones como se muestra en la imagen. Clic en Aceptar.
Ejecute la aplicación (F5) y en la vista general tendrá algo como lo que se observa en la imagen.
1.7.2 Insertar un Nuevo Registro
Vamos ahora a ingresar el código para ingresar un nuevo registro, el código seria el siguiente.
61
Ejecute la aplicación y observe los resultados. Observe lo sencillo de aplicar una clase en C#, adicional a ello tiene la ventaja que reduce mucho código innecesario.
Se debe complementar este formulario con algunos criterios, tales como la validación de cada uno de los campos, que no se envíen campos nulos, etc.; Otra cosa interesante para implementar aquí, es enviarle un correo al administrador informándole que se ha registrado un nuevo usuario, para que él revise el usuario y lo active o elimine según corresponda.
1.7.3 Uso del GridView para trabajar tablas
El GridView es un elemento de ASP.NET que es muy útil al momento de trabajar con las tablas, en las páginas siguientes vamos a ver cómo podemos trabajarlo. Agreguemos un Web Forms llamado frmadminusuarios.aspx. Inserte en este formulario una tabla, con una columna y tres filas, en la segunda fila inserte un GridView, observa la imagen.
62
Vuelva a seleccionar la grilla, clic en la pestaña y en Elegir Origen de Datos, de clic en Nuevo Origen de Datos.
Seleccione la grilla, de clic en la
pestaña superior derecha,
seleccione Formato Automático,
seleccione el de su agrado y de
clic en Aceptar.
63
Selecciona la conexión que ya está allí creada y clic en el Botón Siguiente.
Seleccione la tabla
TbUsuarios y luego de
clic en el botón
Avanzadas, y seleccione
la opción Generar
instrucciones Insert,
Update y Delete y de
clic en Aceptar.
64
Clic en Siguiente y luego Siguiente para finalizar el asistente. El resultado sería como se observa en la imagen.
En las tareas de GridView, habilitar las siguientes opciones:
Ejecute la aplicación y observe los resultados.
Vamos a realizar algunas modificaciones en la grilla, para ver más en detalle las utilidades que tiene, empezaremos por realizar una confirmación en el botón eliminar, ya que si prueba, este botón elimina el registro directamente sin antes pedir confirmación del usuario. 1.7.4 Pedir confirmación del botón eliminar en el GridView Para llevar a cabo el procedimiento, seleccione la grilla y desmarque la opción Habilitar Eliminación.
65
De clic en Editar Columnas
Seleccione
ButtonField y clic
en el botón
Agregar
Propiedad
ButtonType en
Link, Text:
Eliminar y de clic
en la opción que
dice Convertir
este informe en
TemplateField
66
Como resultado tendremos:
Seleccione la grilla, vaya al código asp, ubique las siguientes líneas y haga los cambios correspondientes para que quede como se ubica en el resaltado de la imagen.
Ejecute la aplicación y notará que antes de eliminar el registro, pide confirmación.
Con los botones
de Arriba, Abajo,
si lo desea ubique
el botón eliminar
de segundo (ver
imagen), Clic en el
botón Aceptar.
67
1.7.5 Insertar botón nuevo en el GridView
El GridView debe tener activada sus opciones Habilitar Paginación, Habilitar Ordenación y Habilitar Edición, seleccione la opción Editar Columnas.
Añada un ButtonField a la grilla y establezca su propiedad CommandName en Insert. Los usuarios podrán hacer clic en el botón Insertar para insertar un nuevo registro. En la propiedad Text coloque lo mismo.
Haga clic derecho en el
GridView y seleccione Editar
plantillas, luego EmptyData
Template. Arrastre y suelte un
control DetailsView (opción
Datos) dentro de la planilla,
establezca la propiedad
DataSourceID para
SqlDataSource1, seleccione
Habilitar Inserción
68
Establezca la propiedad DefaultMode en Insertar del DetailsView1, de esta manera cuando la plantilla de datos se muestra, aparece listo para ingresar datos (ver imagen anterior). Ahora vaya al código y escriba el siguiente código en el evento RowCommand del gridView como se muestra a continuación.
En el DetailsView, en el evento ItemInserted, insertar el siguiente código.
69
Ejecute la aplicación y hasta aquí el resultado debe ser como se muestra en las siguientes imágenes.
Seleccione ahora el DetailsView, y en la pestaña tareas de DetailsView, seleccione la opción Editar Plantillas.
Seleccione FooterTemplate e
inserte un botón, tal y como
se ve en la imagen, la
programación del botón será
la siguiente:
70
Haga los cambios correspondientes para que el template quede mejor para el ingreso de datos de parte del usuario, tales como cambiarles el tamaño a los campos de texto, en Universidad debe aparecer el combo con las universidades; En perfil, un combo, al igual que en estado, que en password sea del tipo correspondiente, etc.
1.7.6 Insertar en DropDownList al editar un registro
Ahora edite la plantilla del GridView. En las Tareas del GridView, seleccione la columna de Universidad EditItemTemplate, y allí inserte un DropDownList. Repita el procedimiento hecho para listar las universidades en el combo, como resultado se tiene un SqlDataSource2. Seleccione el DropDownList y vayan a propiedades.
Seleccione el
GridView, seleccione
la opción Editar
Columnas, seleccione
las columnas en las
cuales desea ingresar
el DropDownList
(Universidad, Perfil), y
de clic en la opción
Convertir Este
Informe en
TemplateField. Clic en
Aceptar para finalizar.
71
Seleccione el DropDownList, y seleccione Editar Enlace de Datos, deje los valores como se observan en la imagen.
Verifique que las
propiedades del
DropDownList están
como se observan en la
figura.
72
Ejecute la aplicación y observe los cambios. Se recomienda hacer lo mismo con el Perfil de Usuario.
1.7.7 Validación de Usuarios y perfil
Crear dos nuevos master pages, MasterDocente.aspx y MasterEstudiante.aspx y dos Web Pages, frmmenudocente.aspx (Cuya master page será MasterDocente) y frmmenuestudiante.aspx (Cuya master page será MasterDocente).
Abrir el código donde se valida el usuario y hacer la siguiente modificación.
73
Y modificar la clase funciones.
74
1.7.8 Envío de Correo desde ASP.NET
Frmcontacto.aspx
Código de Botón Enviar. Importar la librería
Cambiar los datos de acuerdo a una cuenta de ustedes, este método de envío de correspondencia usa una autenticación SMTP, para que funcione con una cuenta de ustedes, deben tener una cuenta con éstas características.
75
1.7.9 Módulo Entrenador proyecto Pruebas SaberPro Inserte un nuevo web forms, el cual llamaremos frmentrenador.aspx. En el nuevo formulario diseñe una vista como la de la imagen. (Inserte un dropdownlist, una GridView y un Boton).
La primera situación que hay que resolver es que en el Combo solamente se deben de listar los componentes de la Universidad del estudiante que está actualmente loqueado. Para ello defina las siguientes variables y dentro del page load, ingrese el siguiente código.
76
Session["NombreUsuario"] = "estudiante"; En esta línea lo que se hace es definir un usuario de los que se tienen registrado en la base de datos, para no estar haciendo el proceso de loqueo, mientras se hacen las respectivas pruebas se puede dejar esto así. Luego se llama una función que lo que hace es retornar la Universidad a la cual pertenece ese usuario. Univ = fun.traerUniversidad(Session["NombreUsuario"].ToString()); Esta línea debe de estar arrojando un error, ya que aún no hemos creado la función, como podrán observar esta función debe estar dentro de la librería. Ya en módulos pasados la habíamos hecho, más sin embargo para aquellos que no la tengan, la pueden copiar.
Hasta aquí pueden ejecutar la aplicación y lo que debe estar haciendo hasta este momento es listar los componentes de esta universidad.
77
Ahora al seleccionar uno de los componentes del combo, debe listarnos las preguntas de ese componente, de la universidad del usuario loqueado. 1.7.10 Seleccionar aleatoriamente registros de una tabla Seleccione el combo y habilite la opción de AutoPostBack, y doble clic para crear el procedimiento.
NumPre = fun.traerPreguntas(Convert.ToInt16(DropDownList1.SelectedValue)); Esta línea de código nos trae el número de preguntas que están configuradas en base de datos para este componente. Como podrán observar falta la función que nos retorna este valor.
78
Ejecute la aplicación, el resultado debe ser como lo que se muestra en la imagen.
Pero, primero no queremos que nos muestre la respuesta correcta y segundo, queremos que nos muestre la imagen. 1.7.11 Mostrar una imagen de una tabla en una grilla Para ello seleccione la grilla, clic en Editar Columnas.
Deselecciona la opción
Generar campos
automaticamente
79
Seleccione uno a uno y coloque de acuerdo a su campo en la base de datos la Propiedad DataField¸de igual manera modifique la propiedad HeaderText¸ esta es para el encabezado que desea colocarle a la grilla. Ejecute la aplicación hasta aquí y el resultado deberá ser:
Agregue cinco
BoundField
80
Ahora debemos de mostrar la imagen. Para ello, seleccione la grilla, y seleccione Agregar nueva columna, configure la siguiente ventana como se ve en la imagen.
Ejecute la aplicación y el resultado será:
81
1.7.12 Validar DropDownList insertado dentro de un GridView Ahora debemos agregar una columna nueva para agregar un Combo, en el cual vamos a seleccionar la respuesta deseada por el usuario. Para ello seleccione la grilla, seleccione Editar Columnas, agregue una nueva opción y de clic en Convertir este informe en TemplateField. En HeaderText, escriba Seleccione. Clic en aceptar.
Clic en editar plantillas y en Item Template, elemine el Label y agregue un DropDownList.
Seleccione el combo y agregue las siguientes opciones.
82
Ejecute la aplicación y observe los resultados.
Bien, ahora se desea que al momento de darle clic en enviar, nos debe guardar un registro en una tabla de cuantas preguntas correctas hubieron y cuantas erradas. Pero antes de esto, vamos a mostrar temporalmente en una lista la respuesta correcta y la respuesta que estamos seleccionando, como para ir viendo el procedimiento paso a paso.
83
El código del botón será:
Ejecute la aplicación, después de seleccionar las respuesta y al dar clic en el botón enviar, en la lista deben aparecer las opciones seleccionadas.
Ahora necesitamos las respuestas correctas, para ello debemos de volver al momento en que llenamos la grilla, tomaremos las respuestas correctas y las guardaremos en un vector. Puede ser también en una cadena de texto, separados por algún signo especial. Hagámoslo usando este último método. Antes del Page_Load public static string cadRes=""; Modifiquemos el dropdownlist1.
84
Modifiquemos ahora el botón enviar.
Ejecute la aplicación, debe mostrar en el listbox, las respuestas del usuario con las respuestas correctas.
85
Pero no nos interesa mostrar esto es una grilla si no guardarlo en la base de datos. La tabla para ello es la siguiente.
Hagan las modificaciones al código para que esto sea posible. Les dejo una muestra de al menos como sacar las correctas y las incorrectas.
Ahora, que se debe de hacer, grabar en la tabla estos datos y se le debe mostrar al usuario un resumen, por ejemplo:
Fecha del entrenamiento: 30/10/2012
Usuario 78742034‐Fredys Simanca Herrera
Componente Escritura
Preguntas Correctas 5
Preguntas Incorrectas 4
Imprimir
86
1.8 Proyecto Banco de Proyectos de Grado Diseño de las tablas. Hasta el momento se deben de tener las siguientes tablas. Base de datos: banproyectos
Tabla: TbUsuarios
Tabla: TbProgramas
87
Tabla: TbPropuestas
Tabla: TbPropuestasEstudiantes
Tabla: TbAreasInvestigacion
Tabla: TbLineasInvestigacion
Tabla: TbFechasPropuestas
88
Hasta ahora estas son las tablas, creadas, más adelante cuando se crearán las que hacen falta. Vamos ahora al diseño del aplicativo en Visual Studio. Cree un nuevo proyecto (banproyectos)
Insertar un page master, llamado master.master, en este master page, diseñe una presentación como la que se observa en la imagen.
Nótese que se ha insertado un menú, puede descargar un menú de internet e insertarlo dentro del master page. Las opciones del menú son:
Inicio
Información General o Qué es el comité o Funciones o Integrantes
Contáctenos
Regístrese
Iniciar Sesión
Mas (Opcional)
Colciencias
Ministerio de Educación
Correo de contacto (Puede ir en el píe de página).
89
Agregar un Web Forms llamado Default.aspx, el cual va a ser nuestra página principal, por ahora pueden escribir algo como lo que se observa en la imagen.
Cuáles son los pasos lógicos a seguir?
Hacer la autenticación de usuarios
Diseñar inicialmente la interfaz de administrador
Hacer ingresos a la base de datos de: o Programas o Áreas de Investigación o Líneas de Investigación o Fechas de Propuestas
Está sería la idea por ahora, para el desarrollo del proyecto. Procesamos entonces a insertar un formulario llamado frmlogin.aspx, al momento de insertar este formulario seleccione la página maestra master.master, y diseñe un formulario de autenticación de usuarios, como el que se puede observar en la imagen.
Cambie las propiedades de los controles.
90
Control Propiedad
TextBox1 Name: TxtLogin
TextBox2 Name: TxtPassword
Para un mejor funcionamiento, vamos a dejar todo lo que tiene que ver con variables y conexiones a la base de datos en una clase llamada Funciones.cs, observe la imagen.
El código de la clase, es el que se observa en la imagen.
Tener presente que debe de hacer las referencias a las librerías para poder trabajar el acceso al SQL Server y en el nombre del servidor, allí debe ir el nombre que tenga en su computador. Ahora nos vamos a frmlogin.aspxfrmlogin.aspx y en la siguiente imagen podrá observar el código del formulario que se incluirá por ahora. Las Librerías:
El código completo de la clase frmlogin:
91
Lo primero que hay que hacer es insertar la referencia a la clase que acabamos de crear (Funciones), dentro del Button1, lo que se hace es hacer la consulta que deseamos, ejecutamos la consulta, con las respectivas variables (DA, DT) y validamos el resultado, si se encuentra por lo menos con un registro que cumpla las condiciones dadas en la consulta, se declaran unas variables de tipo sesión, esto con el propósito de poder tener acceso a estas variables desde cualquier otra parte del proyecto, y dependiendo del perfil del usuario mostrar las opciones del menú. Nótese que se está haciendo referencia a un archivo llamado frmmenu.aspx, este archivo aún no está creado, pero antes de crearlo insertemos tres page master más (masteradmin, masterdocente y masterestudiante). Haga lo necesario para que la interfaz en los tres master quede igual. Ahora si agreguemos el archivo frmmenu.aspx, al momento de agregarlo seleccione como página maestra del archivo la masteradmin.master, ejecute la aplicación, de clic en Iniciar Sesión y observe los resultados. 1.8.1 Cambiar el MasterPage dinámicamente. En el frmmenu.aspx, ingrese dos Label e ingrese el siguiente código.
92
La función es para cambiar la página maestra del archivo dependiendo del perfil del usuario loqueado. Y en el page load se muestra en los dos label las variables de sesión usadas en el formulario anterior, esto solo con el propósito de ver que efectivamente está funcionando el manejo de variables de tipo sesión. Modifiquemos el menú administrador con las siguientes opciones (estas opciones son temporales, son las que necesitamos por ahora, es posible que más adelante se deban incluir más).
Inicio
Fechas o Fechas propuestas o Fechas proyectos
Revisiones o Propuestas o Proyectos
Parámetros o Programas o Áreas Investigación o Líneas Investigación
Seguridad o Nuevo Usuario o Admin Usuarios
Cerrar Cesión Insertar ahora dos formularios, frmprogramas.aspx y frmlogout.aspx, la vista del proyecto debe ir:
93
El diseño del formulario frmprogramas.aspx.
El código del formulario.
Note que hay una función llamada InsertarRegistro, esta función está dentro de la clase Funciones se hace de esta manera para poder invocarla de todos los formularios donde se necesite.
TxtPrograma
GridView ID Grilla
94
1.8.2 La función InsertarRegistro:
Ahora, la idea es mostrar en la parte inferior en la grilla los registros que se van ingresando. Seleccione la grilla, clic en la pestaña de la derecha y Elegir origen de datos y Nuevo Origen de Datos.
Seleccione SQL (Base de Datos) y click en Aceptar.
95
Clic en
el Botón Nueva C
onexió
n
Seleccionar M
icrosoft
SQL Server y clic en
Continuar
Ingresar el n
ombre d
el servidor y
seleccionar la b
ase de dato
s y clic en
Aceptar
96
Clic en el botón Siguiente
Clic en el botón Siguiente
Seleccionamos la tabla de
nuestro interés, en este
caso TbProgramas, y damos
clic en el botón Avanzadas
97
Seleccione la opción de la
imagen y de clic en Aceptar
Clic en el botón Siguiente
Clic en el botón Finalizar
98
Ejecute la aplicación y observe los resultados, deben ser como los que se muestran en la imagen.
Volvamos al diseño del formulario, seleccionamos la grilla y en las tareas de GridView, habilitar las siguientes opciones.
Ejecute la aplicación y observe los resultados.
99
Vamos a realizar algunas modificaciones en la grilla, para ver más en detalle las utilidades que tiene, empezaremos por realizar una confirmación en el botón eliminar, ya que si prueba, este botón elimina el registro directamente sin antes pedir confirmación del usuario. 1.8.3 Pedir confirmación del botón eliminar en el GridView Para llevar a cabo el procedimiento, seleccione la grilla y desmarque la opción Habilitar Eliminación.
De clic en Editar Columnas
Seleccione
ButtonField y
clic en el botón
Agregar
100
Como resultado tendremos.
Seleccione la grilla, vaya al código asp, ubique las siguientes líneas y haga los cambios correspondientes para que quede como se ubica en el resaltado de la imagen.
Propiedad
ButtonType en
Link, Text
Eliminar y de clic
en la opción que
dice Convertir
este informe en
TemplateField
Con los botones
de Arriba, Abajo,
si lo desea ubique
el botón eliminar
de segundo (ver
imagen), Clic en el
botón Aceptar.
101
Ejecute la aplicación y notará que antes de eliminar el registro, pide confirmación. ¡Muy bien! Ahora vamos a devolvernos un poco en la ejecución del proyecto y vamos a hacer el formulario de contáctenos, que está en la parte inicial de nuestro proyecto. Inserte un Web Forms, con el nombre de frmcontacto.aspx, recuerde seleccionar la página maestra (master.master) para este formulario.
Código de Botón Enviar. Importar la librería
102
Cambiar los datos de acuerdo a una cuenta de valida, este método de envío de correspondencia usa una autenticación SMTP, para que funcione, deben tener una cuenta con estas características. 1.8.4 Módulo Administración de Áreas de Investigación (frmareasinvestigacion.aspx). Este formulario es muy igual al anterior (frmprogramas), haga el siguiente diseño que observa en la imagen.
Control TextBox, name = TxtArea No olviden insertar la librería.
Código del Botón Enviar.
103
Repita en este formulario, el procedimiento hecho con el formulario anterior, para agregar una grilla, al final el diseño del formulario debe ser como se observa en la imagen.
1.8.5 Módulo administración de líneas de investigación (frmlineasinvestigacion.aspx) Para este formulario, elaboren el siguiente diseño.
Controles:
DropDownList: Nombre (CmbArea)
TextBox: Nombre (TxtLinea) Al iniciar el formulario la idea es que en el combo de Áreas de Investigación se liste la tabla áreas, para ello en el page load ingrese el siguiente código.
La función llenarCombo, debe ir en el mismo formulario, cuyo código es:
104
Note que en la función llenarCombo, hay una función llamada f.consultarRegistros(), esta función debe ir en la clase Funciones y el código es el siguiente.
Código del botón Cancelar Response.Redirect("frmmenu.aspx");
Código del botón Enviar
1.8.6 Agregar en la grilla un campo de descripción de otra tabla Como les había comentado en, cuando insertamos la grilla para administrar la tabla TbLineasInvestigación, en el campo de IdArea, no era bueno mostrarle al usuario solamente el código del área, ya que para el usuario este código no le dice mayor cosa, lo que podemos hacer entonces es mostrarle el código y el
105
nombre del área. Para ello repita el mismo procedimiento aplicado en las anteriores grillas, pero en la ventana de Configurar la instrucción del Select, seleccionamos la primera condición, observe la imagen.
Ingrese los siguientes comandos para cada una de las opciones que observa en las imágenes.
106
Y terminen el procedimiento normal, como en los anteriores casos. Active las siguientes opciones de las tareas del datagrid
107
Ejecute la aplicación y observe los resultados. Agregue el botón de eliminar, explicado en el formulario de frmprogramas.aspx, para que pida confirmación de eliminación de los registros. La vista general del formulario debe quedar como se observa en la imagen.
De clic en el botón editar, note que en el campo de IdArea, la grilla muestra un código (1,2,2) para el caso de los registros que se ven en la imagen, esto no es conveniente para el usuario, ya que él no tiene forma de saber cuáles son los códigos para una de las áreas, lo ideal es mostrarle un combo con las áreas. Observe la imagen que se muestra a continuación.
108
Para hacer esto, siga los siguientes pasos: Seleccione la grilla, clic en editar columnas, seleccione la columna IdArea y de clic en Convertir Informe en Template Field, observe la imagen.
Vuelva al diseño del formulario y esta vez, seleccione dentro de las opciones de la grilla Editar Plantillas. Y en tareas del grid view, seleccione EditItemTemplate, al seleccionar esta opción debe aparecerle un textbox, elimine el textbox e ingrese un DropDownList, observe la imagen para una mejor guía.
109
Usando el asistente, llene el DropDownList con la tabla TbAreasInvestigacion, como resultado se tiene un SqlDataSource2. Seleccione el DropDownList, y seleccione Editar Enlace de Datos, deje los valores como se observan en la imagen.
Ejecute la aplicación y pruebe que todo esté funcionando. Hasta ahora del módulo Administrador hemos elaborado las opciones de Programas, Áreas de Investigación y Líneas de Investigación. Para dejar este módulo por ahora hasta aquí, inserte un formulario llamado frmlogout.aspx, ha este formulario debe llevarnos la opción de Cerrar Sesión, y en el inserte el siguiente código.
110
Esto lo que hace es que al momento en que el usuario de clic en esta opción el cierra la sesión y se direcciona al Default.aspx, que es el archivo inicial de la aplicación. Por ahora vamos a dejar de a lado el módulo administrador y vamos a la interfaz inicial e insertemos los formularios para las opciones que hacen falta. Ingrese los formularios que hacen falta (observe la imagen). Para todos ellos el master, es el master.master
En los formularios frmfunciones.aspx, frmintegrantes y frmqueeselcomite, lo que debe ir allí es la información respecto al comité de trabajos de grado.
En este punto le deben de hacer falta estos formularios: Frmconfirmar.aspx Frmfunciones.aspx Frmintegrantes.aspx Frmqueeselcomite.aspx Frmregistro.aspx Ya veremos para que es cada uno de ellos.
111
El formulario frmregistro y frmconfirmar, la dinámica del registro es que al momento en que un usuario ingrese sus datos al sistema, inicialmente se graba como un usuario inactivo y se le envía un link al correo que haya registrado para que ingrese a la plataforma y active su cuenta. Empecemos entonces por diseñar el formulario frmregistro.aspx
No olvide la configuración del combo CmbPrograma
Coloque los nombres de los controles iguales a los que se encuentran en la tabla, anteponiéndole tres letras del tipo de control, puede observar los nombres en el código igualmente. (Txt para textbox, Cmb para DropDownList, Ful para FileUpload). El código para el botón Ingresar es el que se observa en la imagen.
Llene el combo con la tabla TbProgramas usando el asistente.
Estas son las opciones del CmbPerfil
112
Observe bien el código, interprete lo que se está haciendo en él. Observe por ejemplo que se ha creado una función llamada enviarCorreo, esto debido a que esto lo vamos a necesitar mucho en el transcurso de la ejecución del proyecto, entonces para no estar duplicando código se crea la función, la función la podemos encontrar en la clase Funciones. Este es el código.
113
Si todo está funcionando al correo debe llegar la confirmación. Observe la imagen.
El resultado
114
Ahora toca hacer el código del formulario frmconfirmar.aspx En vista diseño:
El código:
Lo único nuevo que se encuentra aquí es la instrucción Request.QueryString, esta función lo que hace es tomar el valor de la variable que ha sido enviada por la barra de direcciones.
115
Bien, esto nos deja listo, todo lo que es el módulo inicial, la información del comité de trabajos de grado se debe de buscar o incluir algo allí. Qué sigue? Retomar el módulo Administrador, y continuar con el desarrollo del proyecto. Como trabajo queda hacer las dos opciones del Módulo de Seguridad.
Nuevos Usuarios. La idea aquí es hacer lo mismo que está en frmregistro.aspx¸ pero, aquí no hay necesidad de enviar correo de confirmación, ya que se supone que el que está creando este nuevo usuario es el Administrador, por consiguiente hay que enviar un correo pero informando al que se está registrando que ha sido registrado y cuál es su nombre de usuario y su contraseña. Y, esta vez se le envía el link con direccionamiento al frmlogin.aspx. Cómo segundo a tener en cuenta es que el usuario debe quedar en estado activado. En tercer lugar, en las opciones de perfiles deben aparecer los tres perfiles (Administrador, Docente y Estudiante). Admin Usuarios. Esta opción del módulo, nos debe permitir modificar datos al usuario, eliminar el usuario (no se debe eliminar completamente, solo cambiar su estado a inactivo), pueden hacerlo como mejor puedan, tener presente que aquellos usuarios (estudiantes) que tengan foto, se pueda modificar su foto o eliminar la foto. El formulario frmadminusuarios.aspx, la vista diseño debe quedar como se observa en la imagen a continuación.
116
En programa, debe listarse los programas que se encuentran en la tabla TbProgramas. En perfil, debe aparecer las tres opciones de perfiles: Administrador, Docente y Estudiante.
En el formulario frmadminusuarios.aspx, pueden ver en vista diseño como podría quedar, es una opción, hay múltiples soluciones.
Al dar clic en el Botón Buscar, debe
mostrarme el usuario con el documento
ingresado.
117
Módulo Administrar Fechas. La idea de esta opción es programar las fechas de presentación de las propuestas y proyectos de grado, la tabla es TbFechasPropuestas, cuyo diseño es:
El diseño del formulario, sería como se observa en la siguiente imagen.
Se edita el registro, siempre y cuando encuentre una coincidencia en la base de datos
TbUsuarios, el campo documento no debe ser modificable, ya que es la llave primaria, al dar
clic en Actualizar se guardar los cambios en el registro si los hubiera y vuelve a la pantalla
anterior, al dar clic en el botón Eliminar, se eliminar el registro actual, previa confirmación por
parte del usuario de la operación.
Es recomendable buscar un control para
poder seleccionar la fecha, observe la
siguiente imagen, y en tipo de
documento, Propuestas o Proyectos
118
El código del formulario, botón Enviar
Código del Page Load
En este caso he usado
un control AJAX
Las opciones del combo
119
La función llenarCombo
Y el botón Cancelar
Usando el asistente como en casos anteriores, se debe llenar la grilla con la tabla TbFechasPropuesta, como las opciones que se pueden observar en la siguiente imagen.
Queda pendiente en el módulo Administrador las opciones de Revisar Propuestas y Revisar Proyectos. Adicional a ello se debe tener presente que se debe validar que no es posible tener dos fechas activas, ya sea para las propuestas o para los proyectos. Módulo Estudiante (frmuploaddocumentos.aspx) Opción Upload Documentos. En esta opción la idea es que los estudiantes suban los documentos, ya sea de las propuestas o de los documentos. La tabla para esta opción es la siguiente:
No olvidar validar el
botón del Eliminar
120
TbPropuestas
TbPropuestasEstudiantes
Diseñe el siguiente formulario:
Insertar un ScriptManager, ya que se va a
usar AJAX, en el formulario, en la
siguiente imagen se explicará con detalle
en que momento.
Usando el asistente llene el ComboBox
con la tabla TbLineasInvestigacion
Se llena por código con
la función llenarDirector
La idea es que se llenan los datos de la propuesta, se selecciona el archivo, que debe ser en formato Word, se le da clic en
enviar, y paso seguido él debe mostrarnos la opción de poder seleccionar los estudiantes que están presentando la
presente propuesta, para ello se agregará en otra fila de la tabla, primero un UpdatePanel (AJAX), segundo un Panel, y por
ultimo un formulario y una grilla, observe la imagen.
121
Empecemos por el código del form_load del formulario.
Primero Va un
UpdatePanel Dentro del UpdatePanel,
debe ir un Panel
Diseñe el formulario como se
observa en la imagen.
Esta grilla va enlazada a la tabla
TbPropuestasEstudiantes, pero debe traer
los datos como el título de la propuesta, y
los nombres y apellidos de los estudiantes.
Propiedad ReadOnly en true o
cambiarlo por un label.
122
El código primero valida que existen fechas para subir propuestas activas, si hay fechas activas continua, caso contrario, muestra el mensaje. La función llenarDirector
Código del Botón Enviar
123
Botón Cancelar
124
Código del Botón Aceptar
Código del Botón Terminar
Hasta este momento se debe ejecutar la aplicación y el resultado debe ser como el que se muestra en las imágenes.
Se llenan
los datos y
clic en el
botón
Enviar
125
Se ingresa el documento
del estudiante y Agregar
Este será el resultado,
puede agregar varios
estudiantes.
126
Una validación que debe ir aquí, pero que por cuestiones didácticas no se incluye, se deja como tarea extra‐clase al estudiante es que no se debe permitir ingresar más de tres estudiantes a una propuesta. Para terminar, de clic en el botón Terminar. El proceso para el UpLoad de los proyectos es igual a este, se recomienda crear una carpeta para proyectos, hay muchas validaciones y controles que se deben de tener presente en este formulario, pero se siguen dejando para trabajo extra‐clase. Como ya hemos ingresado las propuestas, volvemos al perfil de administrador, para completar las dos opciones que están pendiente, Revisar Propuestas y Revisar Proyectos.
Opción Propuestas Insertar un nuevo formulario con el nombre, frmrevisarpropuestas.aspx, con página maestra masteradmin.master.
En la grilla solo se deben de listar las propuestas cuyo estado sea Revisión, lo podemos hacer por código o por el asistente, como en pasos previos lo hemos hecho por el asistente, esta vez lo vamos a hacer mediante el uso de código. En el page_load iría el siguiente código.
127
Lo que nos arroja como resultado:
La idea ahora es añadir un botón que nos lleve a otro formulario para ver los detalles de la propuesta. 1.8.7 Seleccionar valor de una celda de un GridView
Seleccionamos la grilla, editamos Tareas
de GridView, en elegir origen de datos,
seleccionamos SqlDataSource1 y luego
clic en Editar Columna
De los Campos
Disponibles seleccione
CommandField y
agregue la opción
Seleccionar, en
Apariencia en mi caso he
seleccionado Image,
para colocar una imagen.
128
Resultado:
En la propiedad
InsertImageURL,
seleccione la imagen
que deseé. Clic en
Aceptar
Si la imagen ha quedado muy
grande, puede convertir la columna
en TemplateField y luego editarla
para poder cambiar el tamaño de la
imagen.
Vaya a las propiedades del GridView
y cree el evento en
SelectedIndexChanged
129
Si todo va bien, el código html sería como se ve en la imagen.
Seleccionamos la grilla, damos doble clic sobre ella e insertamos el siguiente código para probar si efectivamente no está tomando el valor que deseamos, en este caso el número de la propuesta.
Vamos a probar primero, si efectivamente nos está tomando el valor de la columna.
En la propiedad
DataKeyNames de la grilla
escriba o seleccione
NumeroPregunta
130
Ahora, al dar clic sobre el registro vamos a direccionarlo a otro formulario, en donde vamos a mostrar o editar el registro, para que el revisor ingrese los datos. Modifiquemos el código, quedaría como se observa en la siguiente imagen.
Insertar el formulario frmdetallespropuesta.aspx, page master masteradmin.master, con el siguiente diseño.
La idea es que el Comité de Grado se reúne, por consiguiente, se toma el número de propuesta y se graba en una tabla la evaluación del comité con las observaciones hechas a la propuesta.
CmbDirector
CmbEstado Agregar ítems:
Revision, Aprobada, Aprobada
con Condiciones y Rechazada
TxtObservacion
131
El diseño de la tabla: TbEvaluacionPropuestas
Empecemos con el código del formulario. Código del page_load
La función llenarDirector
132
Función traerEstudiantes
El código del botón Enviar
Repasemos las opciones del módulo Administrador.
Inicio OK
Fechas o Programar Fechas OK
Revisiones o Propuestas OK o Proyectos *
Parámetros o Programas OK o Áreas Investigación OK o Líneas Investigación OK
Seguridad o Nuevo Usuario OK o Admin Usuarios OK
Cerrar Cesión OK
133
* Revisiones de Proyectos, el comportamiento de esta opción es el mismo que para propuestas, se debe listar los proyectos que están en estado de revisión, se selecciona el que se desea, se pasa a otro documento y en ese documento se le asignan los dos revisores al proyecto, el comité de trabajo de grado no revisa proyectos, solamente mira la información del proyecto, quien es el director, etc, y asigna los jurados. Debería ser algo como: Frmrevisarproyectos.aspx
La tabla TbProyectos
Al dar clic sobre la imagen, debe llevar a frmdetallesproyectos.aspx, al igual que en la propuesta, el formulario debe ser algo como el que se muestra a continuación.
Si notan en la tabla anterior
está el Número de Propuesta,
con este número podemos
traer de la tabla propuesta la
información correspondiente
al proyecto, esto quiere decir
que un estudiante no podrá
ingresar proyectos si no tienen
la propuesta Aprobada
Campo Auto numérico
134
Esto dejaría listo el módulo de Administrador Las opciones del módulo Estudiante. Inicio Documentos
Upload Propuestas OK
UpLoad Proyectos
Revisiones Propuestas
Revisiones Proyectos Cerrar Sesión Opción UploadProyectos La vista del diseño del formulario.
Se deben de tener presenta algunas consideraciones, en el envío del proyecto.
Qué el estudiante que está subiendo el proyecto tenga la propuesta aprobada
Que haya fecha abierta para subida de proyectos
Que el estudiante no haya subido ya el proyecto para la fecha Opción Revisiones Propuestas. En esta opción lo único que se debe hacer es listar la tabla TbEvaluacionPropuestas, tener presente que el estudiante loqueado solo puede ver la o las evaluaciones de su propuesta. Opción Revisiones Proyectos. Igualmente en esta opción, solo se debe listar la tabla TbEvaluacionProyectos (en el módulo docente se mostrará el diseño de la tabla), tener en cuenta que el estudiante solo puede ver la evaluación de su proyecto. Las opciones del Módulo Docente Inicio Revisión Documentos
Proyectos Cerrar Sesión Opción Proyectos (frmevaluacionproyectos.aspx)
135
El diseño del formulario. El docente solo podrá ver los proyectos asignados a él.
Y por último el formulario donde el deberá subir el proyecto con las correcciones y las observaciones. La tabla TbEvaluacionProyectos
Frmcalificarproyectos.aspx
136
1.9 GENERACIÓN DE REPORTES
Visual Studio 2010 permite trabajar reportes por medio de Reporting Service y Crystal reports, en este caso se explicara cómo crear un reporte con Reporting Service.
Los pasos para crear un proyecto empleando reportes:
En el menú de Visual Studio seleccione la opción Archivo y luego en la opción Nuevo Proyecto.
En la siguiente interfaz se muestra un conjunto de plantillas entre las cuales se encuentra la opción Reporting, una vez se selecciona esta, se presentará un recuadro y allí se elegirá trabajar: Aplicación de informe (es lo mismo para lenguaje C# o VB).
137
Si desea guardar el proyecto en una ruta específica se debe dar clic en el botón , donde se abrirá un explorador de Windows el cual corresponde a la ubicación del directorio como se muestra a continuación:
138
Una vez seleccionado el directorio, se procede a digitar el nombre con el que se creara (Ej:
Reportes) y luego damos clic en el botón para crear el proyecto.
A continuación se despliega el asistente para configurar el origen de los datos que incluiremos en el reporte, para lo cual se selecciona la opción Base de datos y damos clic en el botón
.
A continuación seleccionamos la opción Conjunto de datos y damos clic en el botón .
139
Es indispensable la conexión con la base de datos que requerimos, para ello se debe dar clic en
el botón Nueva conexión.
En la ventana de configuración de la conexión se presenta la opción .
En la opción se presentan los diferentes tipos de base de datos a los cuales podremos conectarnos según el origen de la base de datos, en este caso conectaremos con el Proveedor de datos de .NET Framework para SQL SERVER. Seleccionar origen de datos
(Microsoft SQL Server) y dar clic en botón .
140
Una vez seleccionado el origen de datos, seleccionamos la instancia del servidor SQL (normalmente se instala SQL SERVER la instancia por defecto queda como NOMBRE_EQUIPO\SQLEXPRESS).
Seleccionamos el modo Login al servidor SQL SERVER. Si es por credenciales ingresar el usuario y el password.
Ahora bien, si ya están los parámetros correctos en el origen de datos y la conexión con el servidor se presentara un combo con la lista de las bases de datos de SQL SERVER, procedemos a seleccionar la requerida.
141
Una vez ingresados todos los requisitos de configuración del servidor a continuación podemos
probar la conexión dando clic en el botón .
Si la conexión es satisfactoria, damos clic en el botón de la prueba de conexión y clic
en el botón de la ventana de configuración de la nueva conexión.
(Se puede desplegar la opción cadena de conexión para ver la cadena del datasource para la conexión a la base de datos, como se muestra en la siguiente imagen):
142
Continuamos con el ingreso del nombre con el que se guardara la configuración, dar clic en el
botón .
A continuación se presenta una lista con los objetos de la base de datos entre los cuales están las tablas creadas en Microsoft SQL Server 2008 R2, seleccionamos la tabla que se requiera e
ingresamos el nombre del dataset y dar clic en el botón .
143
En este paso ya obtenemos el origen de datos y los objetos de la base de datos; de allí seleccionamos la tabla donde se encuentran los datos a presentar en el reporte y dar clic en el
botón .
Al dar clic en , con el anterior paso se presentara un asistente para elaborar el informe, en este se observan los campos de la tabla que deben ser parametrizados y serán incluidos en el informe.
144
El asistente permite adicionar funciones de SQL para presentar los datos, como se muestra en la siguiente imagen:
Una vez seleccionados los campos que se presentan en el informe, damos clic en el botón
siguiente, se genera una vista previa del diseño, damos clic en el botón .
El asistente tiene opciones para modificar el color del estilo, una vez seleccionado dar clic en el botón .
145
Una vez configurado el origen de datos y diseñado el informe con el asistente, los controles que se presentan en el formulario son los siguientes:
ReportViewer: este proporciona un entorno de diseño integrado para que pueda generar definiciones de informe de cliente (.rdlc) utilizando datos de cualquier objeto de datos ADO.NET
El reportViewer tiene asociado el reporte de reporting service “Report1.rdlc”.
En el explorador de la solución, encontramos el archivo “Report1.rdlc”.
DataSource: es la fuente de acceso a nuestro origen de datos.
146
Una vez verificado cada uno de los componentes se procede a Compilar la solución.
El reporte se presenta de la siguiente forma:
Reporting Service: trae la opción de exportar el informe a formato EXCEL, PDF o WORD.
El proceso se da seleccionando el formato y se guarda en un directorio.
147
Informe en formato Word:
Informe en formato PDF:
Informe en formato EXCEL
148
1.10 GENERACIÓN DE GRÁFICOS Para este proceso, el manejo de graficas con Reporting service, generalizando básicamente se aconseja seguir los siguientes pasos: 1. Creación de consulta en Microsoft SQL Server 2010 con el fin de que retorne los datos que
se requieren mostrar en la gráfica del reporte. 2. Creación de proyecto en Visual Studio 2010. 3. Agregar objeto reportViewer al formulario del proyecto. 4. Agregar el origen de datos. 5. Agregar un nuevo elemento reporte .rdlc al proyecto. 6. Agregar el objeto grafica en el diseño del reporte. 7. Asociar campos a la gráfica. 8. Asociar reporte y origen de datos al objeto reportViewer 9. Finalmente compilar el proyecto. A continuación se presenta una guía y la descripción de los pasos anteriormente mencionados: Creación de consulta en Microsoft SQL Server 2008 con el fin de que retorne los datos que se requieren mostrar en la gráfica del reporte.
Agregar un nuevo procedimiento almacenado en la base de datos sobre la cual se trabajara para extraer los datos que se verán en el reporte. Para adicionar un nuevo procedimiento almacenado en el ambiente SQL Server Management Studio, expandir los objetos de la base de datos, expandir opción Programación, dar clic derecho sobre: y
seleccionar . Para mayor información vaya al apartado de Procedimientos Almacenados.
149
Crear un procedimiento almacenado, el cual retornara la consulta de los datos que se desean mostrar en la gráfica.
Ejecutar el Procedimiento Almacenado mediante la instrucción EXEC nombre_procedimiento, para asegurarse que la consulta sea exitosa y el resultado sea el esperado.
Creación de proyecto en Visual Studio 2010 Una vez que se tenga lista, por decirlo así, “la capa de datos” en SQL, crear un nuevo proyecto en Visual Studio 2010. Para crear el nuevo proyecto vamos al menú - - .
Seleccionamos el tipo de proyecto y le colocamos el nombre con el que se desea crear.
150
Agregar objeto reportViewer al formulario del proyecto. Cuando ya se tiene cargado el proyecto, abrir el nuevo formulario y del cuadro de herramientas seleccionar el objeto reportViewer. Arrástrelo a la forma para agregar dicho objeto.
Para que el objeto quede del tamaño del formulario, seleccione la propiedad acoplar al contenedor, quedará como se muestra a continuación:
151
Agregar el origen de datos El siguiente paso es adicionar el origen de datos, para agregar el origen de datos dar clic derecho sobre la solución en el explorador de soluciones, seleccione la opción y luego seleccione .
152
Se presentara una lista de los elementos visual C# entre los cuales se encuentra la opción de Datos, selecciónelo y a continuación escoja el tipo de elemento Conjunto de datos. Ingrese el nombre (Ej: DataSet1.xsd) y dar clic en el botón .
En el explorador de soluciones se visualizara en el despliegue de opciones un elemento DataSet.
En el diseñador del DataSet se encuentra la opción o link de ir al Explorador de servidores, este presentara la lista de conexiones a base de datos configurada con anterioridad.
153
Una vez se muestre la ventana del explorador de soluciones se pueden visualizar todos los objetos de la base de datos, en este caso utilizaremos el procedimiento almacenado creado anteriormente. Seleccionar el procedimiento almacenado y agregar objeto al diseñador del dataset.
Una vez se agrega al diseño del DataSet se visualizan los campos que retorna la ejecución del procedimiento almacenado.
154
Agregar nuevo elemento reporte .rdlc al proyecto. Ahora bien, en este punto se tiene un formulario con el componente para ver el reporte y un DataSet parametrizado con los datos que se generan. El siguiente paso será agregar un elemento informe para diseñar el reporte. Para agregar un elemento informe dar clic derecho sobre la solución en el explorador de soluciones, seleccione la opción y luego seleccione .
Se presentara una lista de los Elementos de Visual C# en las Plantillas y escogemos la opción Reporting, al seleccionarlo, escogemos el tipo de elemento Informe. Ingrese el nombre y dar clic en el botón Agregar.
155
Agregar un objeto grafica en el diseño del reporte. Del cuadro de herramientas seleccionar el objeto Gráfico. Arrástrelo al diseñador del reporte para agregar dicho objeto.
Se presentará una ventana con varios tipos de gráfica para implementar, seleccionamos el formato y damos clic en el botón . (A continuación se abre un asistente para agregar un origen de datos, omita el paso, ya que la conexión se encuentra definida en caso tal que se requiera una nueva realice la configuración.)
156
Asociar los campos a la grafica Cuando se agrega el objeto Gráfica al diseñador del reporte se abrirá una ventana Datos de informe en la cual encontramos el DataSet agregado al proyecto y su respectivo origen de datos. Para activar las opciones del objeto para agregar los campos dar doble clic sobre el objeto.
Según requerimiento de datos que se deben mostrar un esquema, donde debemos seleccionar el campo contenedor y agregar en la sección de la gráfica correspondiente. En la gráfica se encuentran tres secciones:
Campos de datos Campos de categoría Campos de serie
157
Se puede modificar la escala de la gráfica, modificando la propiedad LogScale=True y LogBase=número de escala.
Asociar reporte y origen de datos al objeto reportViewer Después de tener el diseño del reporte listo, se debe asociar el reporte al objeto reportViewer que se agregó anteriormente. En este cuando se selecciona se muestra en la parte superior derecha una flecha, seleccionar. Se muestra una ventana con las tareas del objeto y un combo con la opción de elegir el informe, seleccionar el informe correspondiente.
158
En la ventana de las tareas del componente se muestra la opción Elegir orígenes de datos. Seleccionar.
A continuación se presenta el DataSet y la instancia. Seleccionamos la correspondiente.
Verificar en el código del formulario que el enlace de los datos este correcto.
159
Compilar proyecto Ahora solo queda compilar el proyecto. Presione tecla F5 o de clic en el botón compilar de Visual Studio.
Reporte generado:
El reporte ya tiene la opción de exportar diferentes formatos como Excel, PDF o Word.
Seleccione el formato e ingrese el directorio con el nombre que se va a guardar.
160
2. SQL SERVER
2.1 INTRODUCCIÓN A SQL
2.1.1 ¿Qué es SQL?
La sigla que se conoce como SQL corresponde a la expresión inglesa Structured
Query Language (entendida en español como Lenguaje de Consulta
Estructurado), la cual identifica a un tipo de lenguaje vinculado con la gestión de bases
de datos de carácter relacional que permite la especificación de distintas clases de
operaciones entre éstas. Gracias a la utilización del álgebra y de cálculos relacionales,
el SQL brinda la posibilidad de realizar consultas con el objetivo de recuperar
información de las bases de datos de manera sencilla.
El científico Edgar Frank Codd (1923-2003) fue quien propuso un modelo relacional
para las bases de datos y creó un sublenguaje para acceder a los datos a partir del
cálculo de predicados. En base al trabajo de Codd, IBM (International Business
Machines) definió el lenguaje conocido como Structured English Query Language
(SEQUEL).
El SEQUEL se considera el antecesor de SQL, un lenguaje de cuarta generación que
se estandarizó en 1986. La versión más primitiva de SQL, por lo tanto, fue la que se
bautizó como SQL-86 (también conocida como SQL1).
En esencia, el SQL es un lenguaje declarativo de alto nivel ya que, al manejar conjuntos
de registros y no registros individuales, ofrece una elevada productividad en la
codificación y en la orientación a objetos. Una sentencia de SQL puede resultar
equivalente a más de un programa que emplee un lenguaje de bajo nivel.
161
Una base de datos, dicen los expertos, implica la coexistencia de múltiples tipos de
lenguajes. El denominado Data Definition Language (también conocido como DDL) es
aquél que permite modificar la estructura de los objetos contemplados por la base de
datos por medio de cuatro operaciones básicas. SQL, por su parte, es un lenguaje que
permite manipular datos (Data Manipulation Language o DML) que contribuye a la
gestión de las bases de datos a través de consultas.
2.2 LAS CONSULTAS SIMPLES.
2.2.1 Sintaxis de la SELECT (para consultas simples)
La sentencia SELECT nos permite consultar los datos o campos almacenados en una
tabla de la base de datos.
La tabla origen (cláusula FROM)
Esta sentencia Indica la tabla (o tablas) desde la que queremos recuperar los datos. En
el caso de que exista más de una tabla se denomina a la consulta "consulta combinada"
o "join". En las consultas combinadas es necesario aplicar una condición de
combinación a través de una cláusula WHERE.
Selección de columnas
Como ya vimos anteriormente la sentencia SELECT sirve para seleccionar datos de una
tabla específica, si queremos que aparezca todas las columnas de la tabla basta con
colocar SELECT * y nos traerá todas las columnas, pero si solo queremos ver unas
columnas especificas es necesario colocar el SELECT y el nombre de las columnas o
campos que desea ver en las consulta.
A continuación vamos a hacer un ejemplo de las sentencias SELECT y FROM
respectivamente supongamos que tenemos una tabla en nuestra base de datos llamada
162
Tbcarros con los siguientes campos: matricula, marca, modelo, color,
numero_kilometros de la siguiente manera:
Con los siguientes datos en la tabla:
La consulta que se va a realizar es que a partir de la tabla Tbcarros vamos a recuperar
únicamente los campos de matrícula, marca, color, para ellos debemos ejecutar la
siguiente consulta. Para crearla le podemos dar clic derecho a la base y nos aparecerá
una opción que dice New Query.
Una vez hallamos hecho la consulta la ejecutamos lo podemos hacer dando F5 y nos
debe aparecer la siguiente información:
163
2.2.2 Ordenar las filas (ORDER BY)
Presenta el resultado ordenado por las columnas indicadas. El orden puede expresarse
con ASC (orden ascendente) y DESC (orden descendente). El valor predeterminado
es ASC.
Ahora vamos a ver un ejemplo del order by utilizando nuevamente la tabla Tbcarros del
ejemplo anterior vamos a organizar según la marca para ello debemos adicional la
siguiente sentencia:
El resultado debe ser el siguiente:
Si nos damos cuenta lo ha organizado en orden alfabético según la marca.
2.2.3 Las cláusulas DISTINCT / ALL
La sentencia DISTINCT Indica que queremos seleccionar sólo los valores distintos a
una referencia y la referencia ALL indica que queremos seleccionar todos los valores.
Es el valor por defecto y no suele especificarse casi nunca.
164
El resultado sería:
2.2.4 La cláusula TOP
La Sentencia TOP se emplea para obtener sólo una cantidad limitada de registros, la
primera n registros de una consulta.
En este caso solo mostraremos los primeros dos.
2.2.5 La cláusula WHERE
Especifica una condición que debe cumplirse para que los datos sean devueltos por la
consulta. Admiten los operadores lógicos AND, OR y NOT.
165
Para esta sentencia el ejemplo que vamos a realizar es que nos muestre la información
del carro o carros con matriculas 'ZMU-084' O matricula = 'MAA-566' solo tiene que
encontrar la primera ya que la segunda que colocamos no existe en la base de datos ya
que es un condicional O puede encontrar cualquiera de las dos o las dos la consulta
seria de la siguiente forma:
Y el resultado sería el siguiente:
Como nos podemos dar cuenta solo nos muestra la información de un solo carro que
cumple con la condición de la matrícula. En cuanto el operador lógico AND se trabaja
en la misma sentencia únicamente cambiamos donde está el OR en la consulta anterior
por el AND con este operador lógico si es necesario que las dos condiciones se
cumplan para que pueda ver el resultado. El NOT nos muestra todos menos el dato que
coloquemos en la consulta.
Operadores permitidos en la sentencia WHERE
Con la sentencia WHERE, los siguientes operadores pueden ser usados:
166
2.2.5 Condiciones de selección
Las condiciones de selección son las condiciones que pueden aparecer en la cláusula WHERE.
En SQL tenemos cinco condiciones básicas:
Test de comparación: Compara el valor de una expresión con el valor de otra.
= igual que <> distinto de < menor que
<= menor o igual > mayor que
>= mayor o igual
Ejemplo:
Mostrar los carros que sean modelo mayor al 1996.
Test de rango: Examina si el valor de la expresión está comprendido entre los dos
valores definidos por exp1 y exp2. (Between).
167
Ejemplo:
Consultar carros modelos entre 2000 y 2008.
Test de pertenencia a un conjunto: Examina si el valor de la expresión es uno de
los valores incluidos en la lista de valores.
Test de valor nulo: Una condición de selección puede dar como resultado el valor
verdadero TRUE, falso FALSE o nulo NULL
Ejemplo
Consultar los carros que no tiene registrado color.
Resultado:
168
En este caso no salió ningún resultado por que el color lo dejamos como No Null.
Test de correspondencia con patrón: Se utiliza cuando queremos utilizar
caracteres comodines para formar el valor con el compara
Ejemplo:
Consultar todos los carros que sean Nissan:
2.2.6 Caracteres Comodines
Los comodines SQL pueden ser usados en la búsqueda de datos en una base de datos
pueden sustituir a uno o más caracteres cuando se busquen los datos
Los comodines deben usarse con el operador LIKE Se pueden usar con SQL los
siguientes comodines:
169
COMODÍN SIGNIFICADO
% Cualquier cadena de cero o más caracteres. _ Cualquier carácter. [] Cualquier carácter individual del intervalo (por ejemplo [abcdef]) especificado. [^] Cualquier carácter individual fuera del intervalo (por ejemplo [^a ‐ f) especificado.
Ejemplo
Ahora seleccionaremos los carros que empiecen con "ZM" la matricula.
2.3 LAS CONSULTAS MULTITABLA
2.3.1 La unión de tablas Esta operación se utiliza cuando se tienen dos tablas con las mismas columnas y se quiere obtener una nueva tabla con las filas de la primera y las filas de la segunda. Cuando se habla de tablas pueden ser tablas reales almacenadas en la base de datos o tablas lógicas (resultado de una consulta), esto permite utilizar la operación con más frecuencia ya que pocas veces se tiene en una base de datos tablas idénticas en cuanto a columnas. El resultado siempre es una tabla lógica. El operador que permite realizar esta operación es el operador UNION.
170
Fuente: www.aulaclic.com/sql 2.3.2 La composición de tablas La composición de tablas consiste en concatenar filas de una tabla con filas de otra. En este caso se obtiene una tabla con las columnas de la primera tabla unida a las columnas de la segunda tabla, y las filas de la tabla resultante son concatenaciones de filas de la primera tabla con filas de la segunda tabla.
Fuente: www.aulaclic.com/sql Existen distintos tipos de composición, se utiliza siempre el más apropiado según el caso. Los tipos de composición de tablas son:
El producto cartesiano El INNER JOIN El LEFT / RIGHT JOIN
El operador UNION El operador UNION combina el resultado de dos o más instrucciones SELECT en un único conjunto de resultados. Se utiliza el operador UNION cuando los datos que se desean residen en ubicaciones diferentes y no se puede tener acceso a ellos con una única consulta. Al utilizar el operador UNION, tenga en cuenta los siguientes hechos e instrucciones:
171
SQL Server requiere que las tablas a las que se hace referencia tengas tipos de datos similares, el mismo número de columnas y el mismo orden de columnas en la lista de selección de cada consulta. SQL Server quita las filas duplicadas del conjunto de resultados. Sin embargo, si utiliza la opción ALL, se incluyen todas las filas en el conjunto de resultados. Debe especificar los nombres de las columnas en la primera instrucción SELECT. Por lo tanto, si desea definir nuevos encabezados de columnas en el conjunto de resultados, deberá crear los alias de columnas en la primera instrucción SELECT. Sintaxis lógica del operador: Instrucción SELECT UNION [ALL] Instrucción SELECT Se presenta el siguiente ejemplo:
Se utiliza el operador UNION
El resultado es:
172
El Producto Cartesiano El producto cartesiano es un tipo de composición de tablas, aplicando el producto cartesiano a dos tablas se obtiene una tabla con las columnas de la primera tabla unidas a las columnas de la segunda tabla, y las filas de la tabla resultante son todas las posibles concatenaciones de filas de la primera tabla con filas de la segunda tabla. La sintaxis es la siguiente: FROM nombreTabla AS aliasTabla El producto cartesiano se indica poniendo en la FROM las tablas que queremos componer separadas por comas, podemos obtener así el producto cartesiano de dos, tres, o más tablas. Para el ejemplo las dos tablas de donde se consultan los datos están de la siguiente manera:
173
El resultado implementando el producto cartesiano es el siguiente:
El INNER JOIN El INNER JOIN es otro tipo de composición de tablas, permite emparejar filas de distintas tablas de forma más eficiente que con el producto cartesiano cuando una de las columnas de emparejamiento está indexada. Ya que en vez de hacer el producto cartesiano completo y luego seleccionar la filas que cumplen la condición de emparejamiento, para cada fila de una de las tablas busca directamente en la otra tabla las filas que cumplen la condición, con lo cual se emparejan sólo las filas que luego aparecen en el resultado. La sintaxis es la siguiente: FROM tabla1 INNER JOIN tabla2 ON tabla1.col1 comparar tabla2.col2 Por ejemplo en una base de datos donde se gestionan notas, se consultara el nombre del estudiante y que materias tiene suscritas.
174
El resultado es:
El LEFT JOIN y el RIGHT JOIN El LEFT JOIN y RIGHT JOIN son otro tipo de composición de tablas, también denominada composición externa. Son una extensión del INNER JOIN. La sintaxis del LEFT JOIN es la siguiente: FROM tabla1 LEFT JOIN tabla2 ON tabla1.col1 comparar tabla2.col2 La descripción de la sintaxis es la misma que la del INNER JOIN, lo único que cambia es la palabra INNER por LEFT (izquierda en inglés). Esta operación consiste en añadir al resultado del INNER JOIN las filas de la tabla de la izquierda que no tienen correspondencia en la otra tabla, y rellenar en esas filas los campos de la tabla de la derecha con valores nulos. En el siguiente ejemplo se busca traer también las materias que no está viendo ningún estudiante.
175
El resultado es:
La sintaxis del RIGHT JOIN es la siguiente: FROM tabla1 RIGHT JOIN tabla2 ON tabla1.col1 comparar tabla2.col2 La sintaxis es la misma que la del INNER JOIN, lo único que cambia es la palabra INNER por RIGHT (derecha en inglés). Esta operación consiste en añadir al resultado del INNER JOIN las filas de la tabla de la derecha que no tienen correspondencia en la otra tabla, y rellenar en esas filas los campos de la tabla de la izquierda con valores nulos. En el siguiente ejemplo se busca traer solamente las materias que están viendo ningún estudiante.
El resultado es:
176
2.3.3 Las funciones de Columna En la lista de selección de una consulta de resumen aparecen funciones de columna también denominadas funciones de dominio agregadas. Una función de columna se aplica a una columna y obtiene un valor que resume el contenido de la columna. Las siguientes son funciones de columna: SUM (expresión) AVG (expresión) STDEV (expresión) STDEVP (expresión) MIN (expresión) MAX (expresión) COUNT (expresión) COUNT (*) La función SUM() calcula la suma de los valores indicados en el argumento. Los datos que se suman deben ser de tipo numérico (entero, decimal, coma flotante o monetario...). El resultado será del mismo tipo aunque puede tener una precisión mayor.
StDev() y StDevP() calculan la desviación estándar de una población o de una muestra de la población representada por los valores contenidos en la columna indicada en el argumento. Si la consulta base (el origen) tiene menos de dos registros, el resultado es nulo. AVG(), STDEV(), STDEVP() los resultados no serán los mismos con valores 0 que con valores nulos. Veámoslo con un ejemplo:
Las funciones MIN() y MAX() determinan los valores menores y mayores respectivamente. Los valores de la columna pueden ser de tipo numérico, texto o fecha. El resultado de la función tendrá el mismo tipo de dato que la columna. Si la columna es de tipo numérico MIN() devuelve
177
el valor menor contenido en la columna, si la columna es de tipo texto MIN() devuelve el primer valor en orden alfabético, y si la columna es de tipo fecha, MIN() devuelve la fecha más antigua y MAX() la fecha más reciente. La función COUNT(nb columna) cuenta el número de valores que hay en la columna, los datos de la columna pueden ser de cualquier tipo, y la función siempre devuelve un número entero. Si la columna contiene valores nulos esos valores no se cuentan, si en la columna aparece un valor repetido, lo cuenta varias veces.
COUNT(*) permite contar filas en vez de valores. Si la columna no contiene ningún valor nulo, COUNT(nbcolumna) y COUNT(*) devuelven el mismo resultado, mientras que si hay valores nulos en la columna, COUNT(*) cuenta también esos valores mientras que COUNT(nb columna) no los cuenta.
Selección en el origen de datos El origen de datos se encuentra en la cláusula FROM la cual es una lista separada por comas de nombres de tablas, nombres de vistas y clausulas JOIN. Si queremos eliminar del origen de datos algunas filas, basta incluir la cláusula WHERE que ya conocemos después de la cláusula FROM. Origen múltiple Si los datos que necesitamos utilizar para obtener el resumen se encuentran en varias tablas, se debe formar el origen de datos adecuado en la cláusula FROM como si fuera una consulta multitabla normal. 2.3.4 La cláusula GROUP BY
Agrupa un conjunto de filas seleccionado en un conjunto de filas de resumen de acuerdo con los valores de una o más columnas o expresiones. Se devuelve una fila para cada grupo. Las funciones de agregado de la lista de selección de la cláusula SELECT proporcionan información sobre cada grupo en lugar de filas individuales. La cláusula GROUP BY tiene una sintaxis que cumple la norma ISO y otra sintaxis que no cumple dicha norma. Solo se puede usar un estilo de sintaxis en cada instrucción SELECT.
178
En el ejemplo siguiente se recupera el promedio de las notas obtenido por estudiante en el semestre:
El resultado es:
2.3.5 La cláusula HAVING Especifica una condición de búsqueda para un grupo. HAVING solo se puede utilizar con la instrucción SELECT. Normalmente, HAVING se utiliza en una clausula GROUP BY. Cuando no se utiliza GROUP BY, HAVING se comporta como una clausula WHERE. En el ejemplo siguiente, donde se utiliza una clausula HAVING simple, se recupera el total de cada promedio de estudiante por semestre que obtuvo más del 3,0.
El resultado es:
179
2.4 PROCEDIMIENTOS ALMACENADOS
Un procedimiento almacenado (stored procedure en inglés) es un programa el cual es almacenado
físicamente en una base de datos. Su implementación varía de un manejador de bases de datos a otro.
La ventaja de un procedimiento almacenado es que al ser ejecutado, en respuesta a una petición de
usuario, es ejecutado directamente en el motor de bases de datos, el cual usualmente corre en un
servidor separado. Como tal, posee acceso directo a los datos que necesita manipular y sólo necesita
enviar sus resultados de regreso al usuario, deshaciéndose de la sobrecarga resultante de comunicar
grandes cantidades de datos salientes y entrantes. Usos típicos para procedimientos almacenados
incluyen la validación de datos siendo integrados a la estructura de base de datos (los procedimientos
almacenados utilizados para este propósito a menudo son llamados disparadores; triggers en inglés), o
encapsular un proceso grande y complejo. El último ejemplo generalmente ejecutará más rápido como
un procedimiento almacenado que de haber sido implementado como, por ejemplo, un programa
corriendo en el sistema cliente y comunicándose con la base de datos mediante el envío de consultas
SQL y recibiendo sus resultados. Los procedimientos pueden ser ventajosos: Cuando una base de datos
es manipulada desde muchos programas externos. Al incluir la lógica de la aplicación en la base de datos
utilizando procedimientos almacenados, la necesidad de embeber la misma lógica en todos los
programas que acceden a los datos es reducida. Esto puede simplificar la creación y, particularmente, el
mantenimiento de los programas involucrados. Podemos ver un claro ejemplo de estos procedimientos
cuando requerimos realizar una misma operación en un servidor dentro de algunas o todas las bases de
datos y a la vez dentro de todas o algunas de las tablas de las bases de datos del mismo. Para ello
podemos utilizar a los Procedimientos almacenados autocreables que es una forma de generar ciclos
redundantes a través de los procedimientos almacenados.
180
2.4.1 Creación Procedimiento Almacenado (Sin Parámetros De Entrada)
En la cabecera de definición de un procedimiento almacenado primero se escriben las palabras
reservadas CREATE PROCEDURE a continuación el nombre del procedimiento de almacenamiento
dejando un espacio en blanco.
En tercer lugar la lista de los parámetros cada uno de ellos debe empezar con @ no se colocan entre
paréntesis, va cada parámetro con su tipo de dato, y van separados por comas no se indica nada si son
de entrada, sin embargo si el parámetro es de entrada – salida se incluye al final la palabra reservada
OUTPUT.
CREATE PROCEDURE NombreProcedimiento @Param1 int, @Param2 int, @Param3 int OUTPUT AS BEGIN -- aqui vienen las instrucciones del procedimiento almacenado END
Ya veremos que los parámetros de cursor se utiliza una cláusula diferente; por último un parámetro
puede tener un valor por omisión además también hay que decir que no hay un marcador que indique
donde termina un procedimiento almacenado, muchas veces se coloca la palabra GO al final de cada
procedimiento lo cual considera que el procedimiento termina, antes de la palabra GO o hasta el final
del fichero lo que ocurra primero. Encerrar BEGIN las líneas del procedimiento entre las palabras BEGIN
y END (Final del Procedimiento).
2.4.2 Ejecutar Un Procedimiento Almacenado
Se utiliza la instrucción EXECUTE y a continuación espacio en blanco el nombre del procedimiento
almacenado si tienen parámetros se deben añadir todos los parámetros separados por comas se debe
repetir la cláusula OUTPUT para poder recibir valores en un parámetro de salida si no se incluye OUTPUT
habrá tratado el parámetro en una dirección de entrada.
EXECUTE NombreProcedimiento
2.4.3 Forma General de un Procedimiento Almacenado
En conclusión un Procedimiento almacenado se crea con las palabras reservadas CREATE PROCEDURE a
continuación el nombre, luego se colocan los parámetros con su tipo de dato. Se deben encerrar las
instrucciones entre las palabras reservadas BEGIN Y END luego se debe ejecutar el programa el cual se
almacena en el Servidor.
181
En la siguiente imagen se puede ver el ejemplo de un procedimiento almacenado.
2.4.4 Modificación de un Procedimiento Almacenado
Para modificar el procedimiento almacenado se debe realizar con la palabra ALTER después del nombre
colocar los parámetros.
182
Un repaso general
183
184
Usos. Los usos 'típicos' de los procedimientos almacenados se aplican en la validación de datos,
integrados dentro de la estructura del banco de datos. Los procedimientos almacenados usados con tal
propósito se llaman comúnmente disparadores o triggers. Otro uso común es la 'encapsulación' de un
API para un proceso complejo o grande que podría requerir la 'ejecución' de varias consultas SQL, tales
como la manipulación de un 'dataset' enorme para producir un resultado resumido.
También pueden ser usados para el control de gestión de operaciones, y ejecutar procedimientos
almacenados dentro de una transacción de tal manera que las transacciones sean efectivamente
transparentes para ellos.
Ventajas. La ventaja de un procedimiento almacenado, en respuesta a una petición de usuario, está
directamente bajo el control del motor del manejador de bases de datos, lo cual corre generalmente en
un servidor separado de manejador de bases de datos aumentando con ello, la rapidez de
procesamiento de requerimientos del manejador de bases de datos. El servidor de la base de datos tiene
acceso directo a los datos necesarios para manipular y sólo necesita enviar el resultado final al usuario.
Los procedimientos almacenados pueden permitir que la lógica del negocio se encuentre como un API en
la base de datos, que pueden simplificar la gestión de datos y reducir la necesidad de codificar la lógica
en el resto de los programas cliente. Esto puede reducir la probabilidad de que los datos sean
corrompidos por el uso de programas clientes defectuosos o erróneos. De este modo, el motor de base
de datos puede asegurar la integridad de los datos y la consistencia, con la ayuda de procedimientos
185
almacenados. Algunos afirman que las bases de datos deben ser utilizadas para el almacenamiento de
datos solamente, y que la lógica de negocio sólo debería ser aplicada en la capa de negocio de código, a
través de aplicaciones cliente que deban acceder a los datos. Sin embargo, el uso de procedimientos
almacenados no se opone a la utilización de una capa de negocio.
A continuación nos detenemos a explicar la forma general de un procedimiento almacenado y como se
modifica utilizando la palabra reservada ALTER. Se explica cómo es posible utilizar parámetros de
entrada y como ejecutar un procedimiento almacenado con parámetros de entrada. Al final también se
detalla cómo utilizar valores por defecto para los parámetros de entrada.
Vamos a ejecutar un ejemplo con procedimientos almacenados a través de parámetros, vamos a
emplear la base de datos customers.
En esa Base de datos se va escoger una selección donde aparezca Identificador, el número de la
compañía, el contacto y del país.
Se va a crear un procedimiento que se llame Clientes como ya nos encontramos dentro de Northwind no
tenemos ningún problema, ejecutamos.
En la parte de abajo y después de darle ejecutar nos debe mostrar el mensaje de que ha sido creado
correctamente.
Como ya lo hemos ejecutado y no hemos dado ningún parámetro de entrada ni de salida debemos
ejecutar el procedimiento Clientes lo seleccionamos y damos ejecutar.
Como podemos ver nos devuelve 93 filas pero en realidad nos está devolviendo todas las filas todos los
registros de la tabla aunque solo nos devuelva 4 campos por registro.
186
Vamos a cambiar un poco nuestro procedimiento para que sea más flexible nuestra consulta, vamos a
decirle que nos filtre por los clientes ingleses. Simplemente añadimos la cláusula que se muestra.
Como se había mencionado anteriormente para alterar un procedimiento que ya está creado debemos
emplear la sentencia ALTER
Procedemos a ejecutarlo y nos debe mostrar que lo ha ejecutado correctamente.
Por cierto una manera de ver los procedimientos es dirigirse a la ventana de la derecha minimizamos
tabla dando clic en el símbolo –
187
Lo que nos va a aparecer es todo lo que representa la base de datos.
Después de esto debemos desplegar el menú denominado Procedimientos Almacenados luego
buscamos el procedimiento Clientes.
A continuación ejecutamos clientes simplemente seleccionamos y damos ejecutar.
EXECUTE Clientes
Nos debe mostrar a continuación 7 filas y como le habíamos dicho nos debe devolver los clientes ingleses
únicamente los cuatro campos y esta filtrado como lo habíamos indicado que lo realizara en la tabla
anterior.
Después de observar esto
desplegamos el menú de
programación dando clic
en el símbolo +
Luego de encontrar el procedimiento Clientes desplegamos el menú, aparece otro con nombre Parámetros y aparece uno que dice Devuelve entero en este momento no nos muestra los parámetros.
188
Pero como se había indicado anteriormente a un procedimiento almacenado se le pueden añadir
parámetros de entrada, así que probaremos colocando clientes ingleses, clientes españoles, clientes
brasileños. Para realizar esto debemos ingresar el parámetro que se muestra, pero antes de esto
debemos ingresar un parámetro de entrada le otorgamos una variable en este caso será @País.
No olvidemos agregar los parámetros para los debidos clientes según lo tengamos en la tabla deberían ser como se muestra en la imagen y otro parámetro de entrada colocando la palabra ALTER, el nombre de la variable @País
Lo demás es lo mismo que lo que habíamos hecho anteriormente lo único que cambia es la cláusula Where y ese valor se asocia a la variable @Pais Se ejecuta el procedimiento almacenado, el resultado es clientes ingleses, españoles o los clientes brasileños, según sea el caso. Ahora generamos un valor por defecto, se añade después de la variable el valor por defecto, que el string sea cualquier numero o letras, frase o palabra, la consulta es la misma. Ejecutamos clientes y nos debe traer todos.
189
Ejecute el procedimiento almacenado para cada caso, y observe los resultados. Observe con los siguientes ejemplos: EXECUTE Clientes 's%' EXECUTE Clientes '[a-d]%' EXECUTE Clientes '%p%' Observe que ocurre para cada caso.
2.5 TRIGGERS EN TRANSACT SQL
Un trigger (o desencadenador) es una clase especial de procedimiento almacenado que se ejecuta
automáticamente cuando se produce un evento en el servidor de bases de datos.
Los desencadenadores DML se ejecutan cuando un usuario intenta modificar datos mediante un
evento de lenguaje. Los eventos DML son instrucciones INSERT, UPDATE o DELETE de una tabla.
Estos desencadenadores se activan cuando se desencadena cualquier evento válido, con
independencia de que las filas de la tabla se vean o no afectadas.
Los desencadenadores DDL se ejecutan en respuesta a una variedad de eventos de lenguaje de
definición de datos (DDL). Estos eventos corresponden principalmente a instrucciones CREATE,
ALTER y DROP.
Los desencadenadores logon se activan en respuesta al evento LOGON que se genera cuando se
establece la sesión de un usuario. Los desencadenadores se pueden crear directamente a partir de
instrucciones Transact‐SQL o de métodos de ensamblados que se crean en Microsoft.NET y se cargan
en una instancia de SQL Server. SQL Server permite crear varios desencadenadores para una
instrucción específica.
2.5.1 Los Desencadenadores DML
La sintaxis general de un trigger es la siguiente.
190
Las instrucciones de triggers DML utilizan dos tablas especiales
La primera tabla (inserted) solo está disponible en las operaciones INSERT y UPDATE y en ella
están los valores resultantes después de la inserción o actualización. Es decir, los datos
insertados. Inserted estará vacía en una operación DELETE.
En la segunda (deleted), disponible en las operaciones UPDATE y DELETE, están los valores
anteriores a la ejecución de la actualización o borrado. Es decir, los datos que serán borrados.
Deleted estará vacía en una operación INSERT.
La siguiente instrucción provocará que el trigger se ejecute:
Podemos especificar a qué columnas de la tabla debe afectar el trigger.
191
Podemos activar y desactivar Triggers a través de las siguientes instrucciones.
2.5.2 Los desencadenadores DDL
La sintaxis general de un trigger es la siguiente.
La siguiente instrucción impide que se ejecuten sentencias DROP TABLE y ALTER TABLE en la base de
datos.
2.5.3 Ejemplo práctico de cómo crear un Triggers en Transact SQL
Después de haber conceptualizado toda la parte teórica de lo que es un trigger y cómo funciona
procederemos con el desarrollo de nuestro ejemplo.
Ingrese a SQL Server 2008 o 2005, inicio‐>todos los programas‐>Microsoft SQL Server 2008 o 2005‐>SQL
Management Studio.
192
Nos conectamos con nuestro usuario y contraseña
Después de habernos conectado procederemos con la creación de una nueva base de datos llamada
MITRIGGER para ello daremos “clic derecho en Base de Datos” y “clic en Nueva base de datos”
Asignamos el nombre de nuestra base de datos y damos clic en Aceptar.
Luego de haber creado nuestra base de datos procederemos a crear 2 tablas de la siguiente manera:
193
La primera tabla se llamará Cliente
Dentro de la tabla Cliente ingresaremos los siguientes campos.
‐IdCliente (pk, varchar(20)), ‐Nombre(varchar(20)), ‐Apellido(varchar(20)), ‐Direccion (varchar(20))
Una vez creada la tabla ingresaremos 3 datos dentro de la tabla de la siguiente forma:
194
Una vez ingresado datos dentro de esta tabla procederemos con la creación de la tabla No. 2
La segunda tabla se llamara Pedidos
Dentro de la tabla Pedidos ingresaremos los siguientes campos.
‐IdCliente (pk, varchar(20)),
‐Nombre(varchar(20)),
‐Fecha(date)
Una vez creada nuestra segunda tabla procederemos con la implementación de nuestro Trigger.
Para proceder con la ejecución de nuestro Trigger vamos a abrir la consola de consultas o ”query” de la
siguiente manera:
Clic derecho sobre la base de datos ya creada y clic en Nueva consulta.
Una vez ingresado a la ventana de consulta procederemos a realizar un:
195
Select * from Cliente Select * from Pedidos Nota: para ejecutar las consultas se da clic en el botón Ejecutar en la parte superior. Para verificar que las tablas creadas están correctas.
El siguiente código lo ingresaran dentro de la consulta con el fin de que el trigger afecte la tabla de
clientes como la de Pedidos con el fin de que nos permita realizar las modificaciones que se deseen.
Una vez digitada seleccione toda la instrucción y de clic en el botón Ejecutar allí aparecerá como
resultado “Comandos completados correctamente.”
196
Realizando nuevamente un:
Select * from Cliente Select * from Pedidos En las tablas podemos notar que aún no hay datos ni modificaciones.
Por lo que procederemos a insertar el siguiente código y notar los cambios que se van a producir
Una vez digitada seleccione toda la instrucción y de clic en el botón Ejecutar allí aparecerá como
resultado (1 filas afectadas).
197
Finalmente realizando nuevamente un:
Select * from Cliente Select * from Pedidos
En ambas tablas podremos observar la manera en que si vieron afectadas mediante la utilización de los
Triggers en Transact SQL
198
2.6 TRANSACCIONES EN TRANSACT SQL
Una transacción es un conjunto de operaciones Transact SQL que se ejecutan como un único bloque, es decir, si falla una operación Transact SQL fallan todas. Si una transacción tiene éxito, todas las modificaciones de los datos realizadas durante la transacción se confirman y se convierten en una parte permanente de la base de datos. Si una transacción encuentra errores y debe cancelarse o revertirse, se borran todas las modificaciones de los datos.
El ejemplo clásico de transacción es una transferencia bancaria, en la que quitamos saldo a una cuenta y lo añadimos en otra. Si no somos capaces de abonar el dinero en la cuenta de destino, no debemos quitarlo de la cuenta de origen.
SQL Server funciona por defecto con Transacciones de confirmación automática, es decir, cada instrucción individual es una transacción y se confirma automáticamente.
Sobre el ejemplo anterior de la transferencia bancaria, un script debería realizar algo parecido a lo siguiente:
199
Esta forma de actuar seria errónea, ya que cada instrucción se ejecutaría y confirmaría de forma independiente, por lo que un error dejaría los datos erróneos en la base de datos (¡y ese es el peor error que nos podemos encontrar!)
2.6.1 Transacciones implícitas y explicitas
Para agrupar varias sentencias Transact SQL en una única transacción, disponemos de los siguientes métodos:
Transacciones explícitas. Cada transacción se inicia explícitamente con la instrucción BEGIN TRANSACTION y se termina explícitamente con una instrucción COMMIT o ROLLBACK.
Transacciones implícitas. Se inicia automáticamente una nueva transacción cuando se ejecuta una instrucción que realiza modificaciones en los datos, pero cada transacción se completa explícitamente con una instrucción COMMIT o ROLLBACK.
Para activar‐desactivar el modo de transacciones implícitas debemos ejecutar la siguiente instrucción.
200
Cuando la opción ANSI_DEFAULTS está establecida en ON, IMPLICIT_TRANSACTIONS también se
establece en ON.
El siguiente ejemplo muestra el script anterior haciendo uso de transacciones explicitas.
201
El siguiente ejemplo muestra el mismo script con transacciones implícitas:
202
La transacción sigue activa hasta que emita una instrucción COMMIT o ROLLBACK. Una vez que la
primera transacción se ha confirmado o revertido, se inicia automáticamente una nueva transacción la
siguiente vez que la conexión ejecuta una instrucción para modificar datos.
La conexión continúa generando transacciones implícitas hasta que se desactiva el modo de
transacciones implícitas.
Podemos verificar el número de transacciones activas a través de @@TRANCOUNT.
203
Otro punto a tener en cuenta cuando trabajamos con transacciones son los bloqueos y el nivel de
aislamiento.
2.6.2 Transacciones anidadas.
Podemos anidar varias transacciones. Cuando anidamos varias transacciones la instrucción COMMIT
afectará a la última transacción abierta, pero ROLLBACK afectará a todas las transacciones abiertas.
Un hecho a tener en cuenta, es que, si hacemos ROLLBACK de la transacción superior se desharán
también los cambios de todas las transacciones internas, aunque hayamos realizado COMMIT de ellas.
Una consideración a tener en cuanta cuando trabajamos con transacciones anidadas es la posibilidad de
utilizar puntos de guardado o SAVEPOINTs.
2.6.3 Puntos de recuperación (SavePoint).
Los puntos de recuperación (SavePoints) permiten manejar las transacciones por pasos, pudiendo hacer
rollbacks hasta un punto marcado por el savepoint y no por toda la transacción.
El siguiente ejemplo muestra cómo trabajar con puntos de recuperación.
204
Características
Las instrucciones básicas de SQL son insertar, consultar, modificar, y eliminar.
En las transacciones existen cuatro características básicas:
Atomicidad: Es la propiedad que asegura que las operaciones se han realizado o no, se realiza el commit
para confirmar o el rollback para deshacer
Consistencia: Es la propiedad que asegura que solo aquello que empieza se puede acabar, por lo tanto se
ejecutan solo las operaciones que no vayan a romper las reglas y directrices de integridad en la base de
datos
Aislamiento: Es la propiedad que asegura que una operación no puede afectar a otras. Esto asegura que
la realización de dos transacciones sobre la misma información sean independientes y no generen
ningún tipo de error
Durabilidad: Es la propiedad que asegura que una vez realizada la operación esta persistirá y no se podrá
deshacer aunque falle el sistema
Begin Transaction
Insert
Update
205
Delete
If Error
Rollback
Else
Commit
Datos importantes para tener en cuenta
Las transacciones permiten agrupar pasos físicos cuando se realizan modificaciones en las bases de
datos.
En las transacciones se consolidan con dos instrucciones básicas
COMMIT: Es la confirmación de la transacción para la modificación de los datos de la base de datos
ROLLBACK: Es la que anula cualquier modificación realizada a la base de datos.
2.6.4 Ejercicio de transacciones
Ingrese al Servidor mediante el Managament Studio.
Cree una base de datos llamada Ventas, dentro de ella una tabla llamada Ventas igualmente, observe la
imagen para ver mejor el diseño.
206
Ubíquese en esta tabla y de clic en la opción de .
Esto nos lleva a la siguiente pantalla.
Digitamos la siguiente instrucción:
Primero procedemos a seleccionar la información de la tabla ventas
y damos click en ejecutar lo cual nos permite ver la siguiente
información
207
Luego ejecutamos los comandos de la transacción.
Empezamos por ejecutar y nos muestra la siguiente información.
Luego ejecutamos el update.
Como podemos ver tenemos 1 fila afectada si deseamos confirmar la operación seleccionamos la
instrucción COMMIT, y ejecutamos la instrucción.
Si no deseamos realizar el cambio
Debemos seleccionar la instrucción ROLLBACK y ejecutarla.
208
Lo que revierte los cambios realizados.
2.7 FUNCIONES EN TRANSACT SQL
Una función definida por el usuario es una rutina de Transact‐SQL que acepta parámetros, realiza una acción, como un cálculo complejo, y devuelve el resultado de esa acción como un valor. El valor devuelto puede ser un valor escalar (único) o una tabla. Utilice esta instrucción para crear una rutina reutilizable que se pueda utilizar de estas formas:
En instrucciones Transact‐SQL como SELECT En las aplicaciones que llaman a la función En la definición de otra función definida por el usuario Para parametrizar una vista o mejorar la funcionalidad de una vista indizada Para definir una columna en una tabla Para definir una restricción CHECK en una columna Para reemplazar un procedimiento almacenado.
En esta Guía se explicaran como crear las siguientes funciones en SQL Server ,para realizar la función en la consola de SQL Server, se selecciona en la parte superior izquierda la opción NUEVO QUERY, como ejemplo la base de datos master que viene por defecto con SQL server 2010 para trabajar los 3 tipos de funciones:
Funciones Escalares
Funciones con valores de tablas de varias instrucciones
Funciones con valores de tabla en línea
2.7.1 Función Escalar
Esta función permite devolver un solo valor, son parecidas a las funciones que se utilizan dentro de los lenguajes de programación se utilizan para cálculos básicos matemáticos ya que devuelven un solo valor es decir un escalar. La función se conforma de la siguiente forma:
Create Function Nombre de la Función (@parametros recibidos tipo de parámetro) Returns Tipo de retorno
209
as Begin Declare variables que necesitamos tipo de variable Sentencias a ejecutar con las variables y los parámetros que recibimos Return variable que retornamos end
Para que la funcion sea almacenada en la base de datos se selecciona y se da click en ejecutar.
Para llamar la función y ser ejecutada se construye un query con la siguiente sintaxis:
Select dbo.NombreFuncion (Valor Parametro ) as NombreColumnaAMostrar From Tabla
Para ejecutar el Query se selecciona y se da click en ejecutar y en la parte inferior se muestran los
resultados.
210
A continuacion se hace otra prueba para verificar el correcto funcionamiento de la funcion.
2.7.2 Funciones con valores de tabla de varias instrucciones
Es un hibrido entre vista y procedimiento almacenado, ya que son consultas con una instrucción select
pero reciben parámetros cosa que no puede hacer la vista ni el parámetro almacenado, el procedimiento
puede encapsular insert, update o un conjunto de instrucciones SQL por lo que la función es más
eficiente de efectuar consultas con parámetros y es la herramienta que se debe preferir para hacer
sentencias de este tipo. La función se conforma de la siguiente forma:
Create Function Nombre de la Función (@parametros recibidos tipo de parámetro) Return @variable table(Campos de la tabla que de va a recibir) As Begin Insert @ variable select campos_tabla from tabla where campo_validacion=@parametros recibidos Return End
211
Para que la funcion sea almacenada en la base de datos se selecciona y se da click en ejecutar.
Para llamar la función y ser ejecutada se construye un query con la siguiente sintaxis:
Select * from nombre_funcion(parametro)
Para ser ejecutar el Query se selecciona y se da click en ejecutar y en la parte inferior se muestran los
resultados.
2.7.3 Funciones con valores de tabla en linea
Son iguales que una función con valores de tabla de varias instrucciones solo que su construcción es algo
diferente pues no se definen variables de tipo Table y no es necesario utilizar las palabras Begin y End.
La función se conforma así:
Create function Nombre_funcion(@parametros recibidostipo de parámetro) Returns table As Return(selectcampos_tabla from tabla where campo_validacion=@parametros recibidos)
212
Para que la funcion sea almacenada en la base de datos se selecciona y se da click en ejecutar.
Para llamar la función y ser ejecutada se construye un query con la siguiente sintaxis:
Select * from nombre_funcion(parametro)
Para ser ejecutar el Query se selecciona y se da click en ejecutar y en la parte inferior se muestran los
resultados.
Hacer todo el capitulo de funciones
213
2.8 CURSORES EN TRANSACT SQL
Puntero que recorre fila a fila un conjunto de resultados obtenidos a partir de una consulta T‐SQL (sentencia SELECT), permite modificar y realizar operaciones con este conjunto de resultados. Son utilizados principalmente en procedimientos almacenados, desencadenadores y Scripts de Transact‐SQL a fin de poner el contenido de un conjunto de resultados a disposición de otras instrucciones de Transact‐SQL. Consiste de dos partes:
Conjunto de resultados del cursor: el conjunto (tabla) de filas resultado de la ejecución del query que se asoció al cursor.
Posición del cursor: Un puntero a una fila dentro del conjunto de resultados.
La posición del cursor indica la fila actual del cursor. Se puede modificar o eliminar esa fila usando las sentencias update o delete. Estas sentencias no utilizan una cláusula WHERE normal (con predicados de condición). En cambio, el cursor identifica la fila, para lo cual debe ser abierto y posicionado en la misma utilizando la sentencia FETCH.
El comando FETCH permite cambiar la posición actual del cursor, moviendo su posición una o más filas en el conjunto de resultados del cursor.
2.8.1 Ventajas de los Cursores
Amplían el procesamiento de los resultados porque:
• Permiten situarse en filas específicas del conjunto de resultados. • Recuperan una fila o bloque de filas de la posición actual en el conjunto de resultados. • Aceptan modificaciones de los datos de las filas en la posición actual del conjunto de
resultados • Aceptan diferentes grados de visibilidad para los cambios que realizan otros usuarios en la
información de la base de datos que se presenta en el conjunto de resultados. • Proporcionan instrucciones de Transact‐SQL en secuencias de comandos, procedimientos
almacenados y acceso de desencadenadores a los datos de un conjunto de resultados.
2.8.2 Estructura de un Cursor
En el siguiente diagrama de flujo se presenta la secuencia lógica que sigue la declaración y ejecución de un cursor.
214
Declare Cursor. Los cursores se declaran utilizando la instrucción DECLARE CURSOR definiendo sus atributos, su comportamiento de desplazamiento y la consulta utilizada para generar el conjunto de resultados sobre el que opera el cursor. Declare Cursor acepta tanto la sintaxis basada en el estándar ISO como la sintaxis que utiliza un conjunto de extensiones de Transact‐SQL. Sintaxis Estándar ISO
Argumentos: INSENSITIVE: Define un cursor que hace una copia temporal de los datos que utiliza. Todas las solicitudes que se realizan al cursor se responden desde esta tabla temporal de tempdb; por tanto, las modificaciones realizadas en las tablas base no se reflejan en los datos devueltos por las operaciones de captura realizadas en el cursor y además este cursor no admite modificaciones.
215
SCROLL: Especifica que están disponibles todas las opciones de captura (FIRST, LAST, PRIOR, NEXT, RELATIVE, ABSOLUTE). Si no se especifica SCROLL en una instrucción DECLARE CURSOR de ISO, la única opción de captura que se admite es NEXT. Ejemplo:
Sintaxis Extendida Transact SQL.
Conjuntos de Argumentos Asignados a un Cursor. Para declarar un cursor se pueden agregar
argumentos que determinan su funcionamiento, como lo es recurrir a tablas temporales, recorrer de
diferentes formas un conjunto de resultados, la aceptación o no de realizar sentencias UPDATE o
DELETE. A continuación se muestran estos argumentos.
Declaración de los Argumentos Global y Local
Local. Específica que el ámbito del cursor es local para el proceso por lotes, procedimiento almacenado o desencadenador en que se creó el cursor. Ejemplo:
Global. Especifica que el ámbito del cursor es global para la conexión. Puede hacerse referencia al nombre del cursor en cualquier procedimiento almacenado o proceso por lotes que se ejecute en la conexión.
216
Ejemplo:
Si no se especifica GLOBAL ni LOCAL, el valor predeterminado se controla mediante la configuración de la opción de base de datos default to local cursor.
Declaración de los Argumentos FORWARD_ONLY y SCROLL
FORWARD_ONLY. Especifica que el cursor sólo se puede desplazar de la primera a la última fila. FETCH NEXT es la única opción de recuperación admitida.
Ejemplo:
SCROLL. Específica que están disponibles todas las opciones de recuperación (FIRST, LAST, PRIOR, NEXT, RELATIVE, ABSOLUTE). Si no se especifica SCROLL en una instrucción DECLARE CURSOR la única opción de recuperación que se admite es NEXT.
Ejemplo:
217
Declaración de los Argumentos STATIC, KEYSET, DYNAMIC y FAST_FORWARD
STATIC. Define un cursor que hace una copia temporal de los datos que va a utilizar. Todas las solicitudes que se realizan al cursor se responden desde la tabla temporal de tempdb; por tanto, las modificaciones realizadas en las tablas base no se reflejan en los datos devueltos por las operaciones de recuperación realizados en el cursor y no admite modificaciones.
Ejemplo:
KEYSET. Especifica que la pertenencia y el orden de las filas del cursor se fijan cuando se abre el cursor. El conjunto de claves que identifica las filas de forma única está integrado en la tabla denominada keyset de tempdb. Ejemplo:
DYNAMIC. Define un cursor que, al desplazarse por él, refleja en su conjunto de resultados todos los cambios realizados en los datos de las filas. Los valores de los datos, el orden y la pertenencia de las filas pueden cambiar en cada operación de recuperación.
Ejemplo:
FAST_FORWARD. Especifica un cursor FORWARD_ONLY, READ_ONLY con las optimizaciones de rendimiento habilitadas. No se puede especificar FAST_FORWARD si se especifica también SCROLL o FOR_UPDATE.
Ejemplo:
218
Declaracion de los Argumentos READ_ONLY, SCROLL_LOCKS, OIPTIMISTIC y TYPE_WARNING
READ_ONLY. Evita que se efectúen actualizaciones a través de este cursor. No es posible hacer referencia al cursor en una cláusula WHERE CURRENT OF de una instrucción UPDATE o DELETE. Esta opción reemplaza la capacidad de actualizar el cursor.
Ejemplo:
SCROLL_LOCKS. Específica que se garantiza que las actualizaciones o eliminaciones posicionadas realizadas a través del cursor serán correctas. No es posible especificar SCROLL_LOCKS si se especifica también FAST_FORWARD o STATIC.
Ejemplo:
OPTIMISTIC. Específica que las actualizaciones o eliminaciones posicionadas realizadas a través del cursor no se realizarán correctamente si la fila se ha actualizado después de ser leída en el cursor. Si la fila se ha modificado, el intento de actualización o eliminación posicionada genera un error. No es posible especificar OPTIMISTIC si se especifica también FAST_FORWARD.
Ejemplo:
TYPE_WARNING. Específica que se envía un mensaje de advertencia al cliente si el cursor se convierte implícitamente del tipo solicitado a otro.
Ejemplo:
219
Compatibilidad entre Argumentos
Se puede especificar múltiples parámetros en la apertura de cursor, pero únicamente un parámetro de cada grupo. Por ejemplo:
Se compara la compatibilidad de todos los cursores, para así crearlos con cada uno de los argumentos vistos antes:
OPEN CURSOR Abre un cursor y lo llena ejecutando la instrucción Transact‐SQL especificada en la instrucción DECLARE CURSOR o SET cursor_variable. Sintaxis:
Argumentos:
• GLOBAL: Especifica que cursor_name hace referencia a un cursor global. • cursor_name: Es el nombre de un cursor declarado. Si existe un cursor global y uno local con el
nombre cursor_name, cursor_name hace referencia al cursor global si se especifica GLOBAL; en caso contrario, cursor_name hace referencia al cursor local.
• cursor_variable_name: Es el nombre de la variable cursor que hace referencia a un cursor. Ejemplo: Abre un cursor y busca todas sus filas.
220
Recuperación de Filas con FETCH
FETCH
Recupera una fila específica de un cursor. Sintaxis:
Parámetros:
NEXT: Devuelve la fila de resultados inmediatamente posterior a la fila actual y aumenta la fila actual a la fila devuelta. Si FETCH NEXT es la primera operación de captura en un cursor, se devuelve la primera fila del conjunto de resultados. NEXT es la opción predeterminada para la captura de cursores.
PRIOR: Devuelve la fila de resultados inmediatamente anterior a la fila actual, y reduce la fila actual a la fila devuelta. Si FETCH PRIOR es la primera operación de captura en un cursor, no se devuelve ninguna fila y el cursor queda posicionado delante de la primera fila.
FIRST: Devuelve la primera fila del cursor y la convierte en la fila actual.
LAST: Devuelve la última fila del cursor y la convierte en la fila actual.
221
ABSOLUTE { n| @nvar}: Si n o @nvar es positivo, se devuelve la fila n desde el principio del cursor y la fila devuelta se convierte en la nueva fila actual. Si n o @nvar es negativo, se devuelve la fila n anterior al final del cursor y la fila devuelta se convierte en la nueva fila actual. Si n o @nvar es 0, no se devuelven filas. n debe ser una constante entera y @nvar debe ser smallint, tinyint oint .
RELATIVE { n| @nvar}: Si n o @nvar es positivo, se devuelve la fila n posterior a la fila actual y la fila devuelta se convierte en la nueva fila actual. Si n o @nvar es negativo, se devuelve la fila n anterior a la fila actual y la fila devuelta se convierte en la nueva fila actual. Si n o @nvar es 0, se devuelve la fila actual. Si se especifica FETCH RELATIVE con n o @nvar se establece en un número negativo o en 0 en la primera operación de captura que se realiza en un cursor, no se devuelven filas. n debe ser una constante entera y @nvar debe ser smallint, tinyint o int.
CLOSE. Cierra un cursor abierto mediante la liberación del conjunto de resultados actual y todos los
bloqueos de cursor mantenidos en las filas en las que está colocado. CLOSE deja las estructuras de datos
accesibles para que se puedan volver a abrir, pero las capturas y las actualizaciones posicionadas no se
permiten hasta que se vuelva a abrir el cursor. CLOSE debe ejecutarse en un cursor abierto, por lo que no
se permite en cursores que sólo están declarados o que ya están cerrados.
Sintaxis:
Argumentos:
GLOBAL: Especifica que cursor_name hace referencia a un cursor global.
cursor_name:Es el nombre de un cursor abierto. Si hay un cursor global y otro local con el nombre cursor_name, cursor_name hace referencia al cursor global si se especifica GLOBAL; de lo contrario, cursor_name hace referencia al cursor local.
cursor_variable_name:Es el nombre de una variable de cursor asociada a un cursor abierto. DEALLOCATE. Quita una referencia a un cursor. Cuando se ha desasignado la última referencia al cursor,
MicrosoftSQL Server libera las estructuras de datos que componen el cursor.
Sintaxis
Argumentos:
cursor_name: Es el nombre de un cursor ya declarado. Si hay un cursor global y otro local con el nombre cursor_name, cursor_name hace referencia al cursor global si se especifica GLOBAL y, si no se especifica GLOBAL, hace referencia al cursor local.
@cursor_variable_name: Nombre de una variable cursor. Debe ser de tipo cursor.
222
Variables Globales @@CURSOR_ROWS, @@FETCH_STATUS y la función CURSOR_STATUS
@@CURSOR_ROWS. Devuelve el número de filas correspondientes actualmente al último cursor abierto
en la conexión. Puede llamar a @@CURSOR_ROWS para determinar que el número de filas que cumplan
las condiciones del cursor se recuperen en el momento en que se llama a @@CURSOR_ROWS.
Ejemplo En este ejemplo se declara un cursor y se utiliza SELECT para mostrar el valor de @@CURSOR_ROWS. La opción tiene el valor 0 antes de abrir el cursor; el valor ‐1 indica que el conjunto de claves del cursor se está llenando de forma asincrónica.
Valor devuelto Descripción
‐m El cursor se rellena de forma asincrónica. El valor devuelto (‐m) es el número de filas que contiene actualmente el conjunto de claves.
‐1 El cursor es dinámico. Como los cursores dinámicos reflejan todos los cambios, el número de filas correspondientes al cursor cambia constantemente. Nunca se puede afirmar que se han recuperado todas las filas que correspondan.
0 No se han abierto cursores, no hay filas calificadas para el último cursor abierto, o éste se ha cerrado o su asignación se ha cancelado.
n El cursor está completamente relleno. El valor devuelto (n) es el número total de filas del cursor.
223
@@FETCH_STATUS. Devuelve el estado de la última instrucción FETCH de cursor ejecutada sobre
cualquier cursor que la conexión haya abierto.
Valor devuelto Descripción
0 La instrucción FETCH se ejecutó correctamente.
‐1 La instrucción FETCH no se ejecutó correctamente o la fila estaba más allá del conjunto de resultados.
‐2 Falta la fila capturada.
Por ejemplo, supongamos que un usuario ejecuta una instrucción FETCH sobre un cursor y a continuación llama a un procedimiento almacenado que abre y procesa los resultados de otro cursor. Cuando vuelve el control desde el procedimiento almacenado llamado, @@FETCH_STATUS reflejará la última instrucción FETCH ejecutada en el procedimiento almacenado, no la ejecutada antes de llamar al procedimiento. Ejemplos Este ejemplo utiliza @@FETCH_STATUS para controlar las actividades del cursor en un bucle WHILE.
CURSOR_STATUS. Una función escalar que permite al que llama a un procedimiento almacenado determinar si el procedimiento ha devuelto un cursor y el conjunto de resultados de un determinado parámetro.
Sintaxis:
CURSOR_STATUS ( { 'local' , 'cursor_name' } { 'global' , 'cursor_name' } { 'variable' , 'cursor_variable' } )
224
Argumentos ‐ 'local': Especifica una constante que indica que el origen del cursor es un nombre local de cursor. ‐ 'cursor_name': Es el nombre del cursor. Un nombre de cursor debe ajustarse a las reglas para los
identificadores. ‐ 'global': Especifica una constante que indica que el origen del cursor es un nombre global de cursor. ‐ 'variable':Especifica una constante que indica que el origen del cursor es una variable local. ‐ 'cursor_variable':Es el nombre de la variable de cursor. Una variable de cursor debe definirse
mediante el tipo de datos cursor.
Valor devuelto
Nombre de cursor Variable de cursor
1 El conjunto de resultados del cursor tiene al menos una fila. Para los cursores INSENSITIVE y de conjunto de claves, el conjunto de resultados tiene al menos una fila. Para los cursores dinámicos, el conjunto de resultados puede tener cero, una o más filas.
El cursor asignado a esta variable está abierto. Para los cursores INSENSITIVE y de conjunto de claves, el conjunto de resultados tiene al menos una fila. Para los cursores dinámicos, el conjunto de resultados puede tener cero, una o más filas.
0 El conjunto de resultados del cursor está vacío.*
El cursor asignado a esta variable está abierto, pero el conjunto de resultados está definitivamente vacío.*
‐1 El cursor está cerrado. El cursor asignado a esta variable está cerrado.
‐2 No aplicable. Puede ser: El procedimiento llamado anteriormente no ha asignado ningún cursor a esta variable OUTPUT. El procedimiento llamado anteriormente asignó un cursor a esta variable OUTPUT, pero se encontraba en un estado cerrado al terminar el procedimiento. Por tanto, se cancela la asignación del cursor y no se devuelve al procedimiento que hace la llamada. No hay ningún cursor asignado a una variable declarada de cursor.
‐3 No existe ningún cursor con el nombre indicado.
No existe una variable de cursor con el nombre indicado o, si existe, no tiene todavía ningún cursor asignado.
*Los cursores dinámicos no devuelven nunca este resultado.
225
Declaración Cursor For Update
Para actualizar los datos de un cursor debemos especificar FOR UPDATE después de la sentencia SELECT en la declaración del cursor, y WHERE CURRENT OF <nombre_cursor> en la sentencia UPDATE.
Ejemplo: ‐‐ Declaración de variables para el cursor
‐‐ Declaración del cursor
‐‐ Apertura del cursor
‐‐ Lectura de la primera fila del cursor
‐‐ Lectura de la siguiente fila del cursor
226
‐‐ Cierre del cursor
‐‐ Liberar los recursos
2.8.3 Asignación y Asociación de Cursores
La instrucción DECLARE CURSOR asigna y asocia un cursor a un nombre de cursor.
Una variable de cursor se puede asociar a un cursor mediante uno de estos dos métodos:
A) Por nombre con una instrucción SET que asocia un cursor a una variable de cursor.
B) También se puede crear y asociar un cursor a una variable sin necesidad de definir un nombre de cursor.
1.15.6 Procedimientos Almacenados y Cursores
Los procedimientos almacenados resultan útiles para la manipulación de cursores, dado que se pueden crear y eliminar cada vez que sea llamado un procedimiento almacenado, además facilitan la tarea de realizar operaciones que conllevarían mayor tiempo para ser solucionadas. Se puede crear un procedimiento almacenado para que cree un cursor o se podría utilizar para que realice cualquier operación, en este caso se muestra la utilización de un procedimiento almacenado para que realice la suma de todos los IDs de una tabla, que son traídos a partir de un cursor.
227
Ejemplo: CREATE PROCEDURE SUMA @SUMA INT OUTPUT AS BEGIN SET @SUMA=0 DECLARE @ID INT DECLARE CURSOR_SUMA CURSOR LOCAL FOR SELECT ID FROM PECES OPEN CURSOR_SUMA FETCH NEXT FROM CURSOR_SUMA INTO @ID WHILE(@@FETCH_STATUS = 0) BEGIN SET @SUMA=@SUMA + @ID FETCH NEXT FROM CURSOR_SUMA INTO @ID END CLOSE CURSOR_SUMA DEALLOCATE CURSOR_SUMA END ‐‐aqui es la transaccion que llama al procedimiento y retorna un valor. DECLARE @SUMA INT EXECUTE SUMA @SUMA OUTPUT SELECT @SUMA
2.9 SQL DINÁMICO EN TRANSACT SQL
En el desarrollo de software cuando se desea crear una aplicación completa para el manejo de una base
de datos relacional, se hace necesaria la implementación de una herramienta que soporte la capacidad
de consulta en SQL y la adaptabilidad a situaciones diversas con facilidad de los lenguajes de
programación tradicionales. Transact SQL es el lenguaje de programación que proporciona SQL Server
para extender el SQL estándar con otro tipo de instrucciones.
Transact SQL permite dos formas de ejecutar SQL dinámico (construir sentencias SQL dinámicamente
para ejecutarlas en la base de datos):
228
La instrucción EXECUTE ‐ o simplemente EXEC
El procedimiento almacenado sp_executesql
INSTRUCCIÓN EXECUTE: permite ejecutar una cadena de caracteres de tipo nvarchar que representa
una sentencia SQL.
El siguiente ejemplo muestra como ejecutar una cadena de caracteres con la instrucción EXEC.
Al ejecutar la sentencia el resultado es el siguiente según los datos del ejemplo:
También con SQL dinámico podemos ejecutar sentencias de tipo DDL (Data Definition Languaje), como
CREATE TABLE, DROP, ALTER. A continuación se presenta un ejemplo.
229
Al ejecutar las instrucciones el resultado obtenido es el siguiente:
2.9.1 Procedimiento Almacenado SP_EXECUTESQL
Para ejecutar sql dinámico, se recomienda utilizar el procedimiento almacenado sp_executesql, en lugar
de una instrucción EXECUTE.
sp_executesql admite la sustitución de parámetros
sp_executesql es más seguro y versátil que EXECUTE
sp_executesql genera planes de ejecución con más probabilidades de que SQL Server los vuelva
a utilizar, es más eficaz que EXECUTE.
230
En el siguiente ejemplo se muestra el uso (muy simple) de sp_executesql.
Al ejecutar la sentencia el resultado es el siguiente según los datos del ejemplo:
sp_executesql admite la sustitución de valores de parámetros para cualquier parámetro especificado en
la cadena Transact‐SQL a ejecutar. El siguiente ejemplo muestra el uso de sp_executesql con
parámetros:
Al ejecutar la sentencia el resultado es el siguiente según los datos del ejemplo:
231
2.10 CERTIFICADOS DIGITALES
Muy breve resumen de la historia de la criptografía En la historia desde hace miles de años que el hombre trata de ocultar sus mensajes y escritos de ojos a los cuales no desea mostrar su contenido, y para esto encripta estos textos utilizando, en un principio, métodos sencillos que incluían el uso de lápiz, papel o alguna máquina sencilla. Luego, a principios del siglo XX, comenzó a utilizar máquinas mecánicas y electromecánicas, como la conocida máquina de rotores llamada Enigma, la cual fue utilizada por las fuerzas Alemanas desde 1930, proporcionando métodos de cifrado más complejos y eficientes. La criptografía moderna comenzó cuando Claude Shannon publicó el artículo Communication Theory of Secrecy Systems en la Bell System Technical Journal en 1949, y poco tiempo después, junto a Warren Weaver, publicaron el libro Mathematical Theory of Communication. Estos documentos, juntos con otros publicados posteriormente, formaron las bases de la teoría de la criptografía, aunque fueron organizaciones gubernamentales secretas (como la NSA) las que siguieron con la investigación. Recién a mediados de los 70 hubieron grandes avances a nivel público: la creación del estándar de cifrado DES (Data Encryption Standard) y la creación de la criptografía asimétrica. Métodos De Cifrado. Los métodos de cifrado de la criptografía moderna se dividen, a gran escala, en dos: cifrado de flujo y cifrado de bloques, y éste último a su vez se divide en cifrado simétrico (con clave secreta) y cifrado asimétrico (con clave pública).
232
Cifrado de flujo. Los algoritmos de cifrado de flujo pueden realizar el cifrado incrementalmente, transformando el mensaje original en un mensaje cifrado bit a bit. Esto lo logra construyendo un generador de flujo de clave, el cual es una secuencia de bits de tamaño arbitrario que puede emplearse para oscurecer el contenido del flujo de datos combinando el flujo de clave con el flujo de datos mediante la función XOR. Si el flujo de clave es seguro, el flujo de datos cifrados también lo será. Este método es utilizado en algunas aplicaciones como el cifrado de conversaciones telefónicas, donde el cifrado en bloques es inapropiado porque los flujos de datos se producen en tiempo real en pequeños fragmentos y las muestras de datos pueden ser muy pequeñas (hasta de 1 bit), y sería un desperdicio rellenar el resto de los bits antes de cifrar el mensaje y transmitirlo. Cifrado por bloques. En este tipo de cifrado el mensaje se agrupa en bloques, por lo general de 128 bits o más, antes de aplicar el algoritmo de cifrado a cada parte de forma independiente utilizando la misma clave. Cifrado simétrico. La criptografía simétrica es el método criptográfico que usa una misma clave para cifrar y descifrar los mensajes. Las dos partes que se comunican deben ponerse de acuerdo de antemano sobre la clave a utilizar y, una vez que ambas tienen acceso a esta clave, el remitente cifra el mensaje utilizándola, lo envía al destinatario, y éste lo descifra con la misma clave. Existen algunos algoritmos muy conocidos, como el DES (Data Encryption Standard), el cual fue un diseño de unidad de cifrado por bloques de gran influencia desarrollado por IBM y publicado como estándar en 1977. Cifrado asimétrico El cifrado asimétrico es el método criptográfico que usa un par de claves para el envío de mensajes. Una de estas claves es pública y se puede entregar a cualquier persona, la otra clave es privada y el propietario debe guardarla de modo que nadie tenga acceso a ella. Los métodos criptográficos garantizan que ese par de claves sólo se puede generar una vez, de modo que se puede asumir que no es posible que dos personas hayan obtenido casualmente el mismo par de claves. Si el remitente usa la clave pública del destinatario para cifrar el mensaje, una vez cifrado, sólo la clave privada del destinatario podrá descifrar este mensaje, ya que es el único que la posee. Por lo tanto se logra la confidencialidad del envío del mensaje, nadie salvo el destinatario puede descifrarlo, ni siquiera la misma persona que generó el mensaje. Si el propietario del par de claves utiliza su clave privada para cifrar el mensaje, cualquiera que posea su clave pública podrá descifrarlo. En este caso se consigue tanto la identificación como la autenticación del remitente, ya que se sabe que sólo pudo haber sido él quien utilizó su clave privada (salvo alguien se la hubiese podido robar). Esta idea es el fundamento de la firma electrónica, de la cual hablamos más abajo. Los sistemas de cifrado de clave pública o sistemas de cifrado asimétricos se crearon con el fin de evitar el problema del intercambio de claves que posee el sistema de cifrado simétrico. Con las claves públicas no es necesario que el remitente y el destinatario se pongan de acuerdo en la clave a emplear. Todo lo que se requiere es que, antes de iniciar la comunicación secreta, el remitente consiga una copia de la
233
clave pública del destinatario. Es más, esa misma clave pública puede ser usada por cualquiera que desee comunicarse con su propietario. Cabe mencionar que aunque una persona lograra obtener la clave pública, no podría descifrar el mensaje encriptado con esta misma clave, sólo podría encriptar mensajes que podrían ser leídos por el propietario de la clave privada.
Certificado Digital Un Certificado Digital es un documento digital mediante el cual un tercero confiable (llamado autoridad de certificación o CA) garantiza la vinculación entre la identidad de un sujeto o entidad y su clave pública. Este documento contiene, entre otros datos, el nombre del usuario y su clave pública. Los certificados digitales tienen distintos usos dependiendo de la finalidad para la cual se lo está utilizando, por ejemplo:
Un certificado digital establece la identidad de un usuario en una red
Los servidores pueden configurarse para permitir el acceso a usuarios con ciertos certificados o asignarle la identidad de un usuario del dominio según su certificado
Los clientes pueden ser configurados para confiar en servidores que presentan ciertos certificados, por ejemplo, los que vienen pre configurados en los navegadores para utilizarse en sesiones SSL.
Los certificados pueden utilizarse para firma documentos electrónicos.
234
Una de las certificaciones más usadas y un estándar en la actualidad en infraestructuras de clave pública PKIs (Public‐Key Infrastructure) es X.509 en su versión 3. Certificado digital X.509. X.509 es un estándar publicado oficialmente en 1988 que especifica, entre otras cosas, formatos estándares para certificados de claves públicas y un algoritmo de validación de la ruta de certificación. En X.509 se define una capa de abstracción para suministrar servicios de autenticación a los usuarios de un directorio X.500. En la actualidad es ampliamente utilizado el formato de certificado digital X.509 v3, por ejemplo, para realizar conexiones seguras a servidores web a través de SSL (Secure Sockets Layer). Este tipo de certificados posee un formato donde guarda distintos datos, por ejemplo, un número de serie, la clave pública del usuario, las fechas de validez del certificado, el nombre del usuario (en formato X.500), etc.
A continuación muestro un ejemplo de un certificado digital: Número de Serie: 21479
Versión X.509: v3
Titular: CN=Gustavo Cantero, [email protected], OU=Persona no verificada –
No amparado bajo el Decreto 427/98 de la IFDAPN, O=Política de Certificación de
Correo Electrónico
Emisor: CN=AC de la Subsecretaría de la Gestión Pública para Certificados de Correo
Electrónico, OU=Política de Certificación en http://ca.sgp.gov.ar, OU=No
amparado por el Decreto 427/98 – IFD APN, OU=Subsecretaría de la Gestión
235
Pública, O=Jefatura de Gabinete de Ministros, L=Ciudad de Buenos Aires, C=AR
Validez (no antes de): mié 03 jun 2009 – 19:14:35, ART
(no después de): jue 03 jun 2010 – 19:14:35, ART
Algoritmo de firma: sha1WithRSAEncryption
Clave Pública: E0EE 9902 0301 3081 8902 8181 00E5 AEA6 F074 5EDA 39A2 CF72 70C2 CC9C
E7D6 014F 51BF 7A83 8851 4B07 B4BC 2D93 C422 AEC0 2026 9774 3C14 D54B
51E4 5F5C 434A 03F6 6F5C 4045 CC95 E27E 6C9C F5F6 2D99 6B6D 7CEC C786
ED61 D89B 47ED B46D 3B19 190D 86E8 C2FD 893E 01F2 850A B7AE 5806 9A60
9211 6AA2 374C B04E EE29 0340 C0CC 84F4 CE64 32F3 F035 D7E7 7B79 0001
Huella digital (MD5): C68C 8538 6454 3D7C 222F 9176 B8D7 479C
Huella digital (SHA1): 4AFC 0115 CC50 0CFD B0D8 B564 68F5 F24E E47B BCFA
2.10.1 Firma Digital
La firma digital hace referencia a un método criptográfico que asocia la identidad de una entidad (una persona o un equipo informático) a un mensaje o documento, pudiendo además, asegurar la integridad del documento o mensaje. Para realizar esto se calcula el hash del documento, se encripta el resultado con la clave privada del certificado del usuario, y se adjunta al documento junto con el certificado (pero sin la clave privada, sólo con la pública).
236
Luego, para verificar la firma del documento, se lo abre, se valida el certificado adjunto (se verifica la fecha de validez, si la entidad emisora es de confianza, etc.), se obtiene la firma (el hash encriptado), se lo desencripta con la clave pública, se calcula el hash del documento (sin la firma) y se verifica que ambos hash, el desencriptado y el calculado, sean iguales.
2.10.2 Utilizar Certificados Digitales Desde .NET Consultar los repositorios de certificados. Como primer paso vamos a recorrer los certificados que tenemos instalados en nuestra máquina. Para esto debemos utilizar la clase X509Store, la cual nos da la posibilidad de consultar un repositorio de certificados, por ejemplo, el repositorio raíz (Root), el repositorio donde están los certificados de las autoridades certificantes (CertificateAuthority), o el repostorio personal (My). También tenemos que elegir la ubicación del certificado, es decir, si vamos a querer consultar los certificados que están a nivel de máquina o de usuario. Tengan en cuenta que si van a utilizar la clase X509Store desde ASP.NET deben leer los certificados que están a nivel de máquina, ya que el usuario ASP.NET rara vez va a tener algún certificado instalado. Luego de elegido el repositorio que queremos abrir debemos utilizar el método Open para que consulte al mismo.
237
Una vez abierto el repositorio, la propiedad Certificates contendrá una colección (basada en la clase X509Certificate2Collection) de los certificados almacenados. Después de utilizar el repositorio no hay que olvidar de cerrar el mismo con método Close. A continuación muestro cómo abrir el repositorio personal y escribir en la consola de debug los nombres y firmas digitales (hash) de cada certificado: Creé un nuevo proyecto web tal y como se muestra en la imagen (Una aplicación de consola).
Ingrese el siguiente código:
238
Aquí está para mayor facilidad, no olviden por favor que no basta con solo copiar sino también analizar que es cada línea de código. using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Diagnostics; namespace CertDigitales { class Program { static void Main(string[] args) { X509Store objStore = new X509Store(StoreName.Root , StoreLocation.CurrentUser ); objStore.Open(OpenFlags.ReadOnly); foreach (X509Certificate2 objCert in objStore.Certificates) Console.WriteLine(objCert.SubjectName.Name + ": " + objCert.Thumbprint); objStore.Close(); Console.ReadKey(); } } } Ejecute la aplicación con F5 y observe los resultados. Se lista por consola el repositorio de certificados digitales que hay en el computador.
239
2.10.3 Consultar la información del certificado y sus extensiones Cada certificado posee una serie de datos. Además de estos datos los certificados poseen extensiones, que definen distintos posibles usos dependiendo de las mismas, y según la extensión poseen distintos datos almacenados. Por ejemplo, en la extensión del tipo “2.5.29.37” (también llamada “Enhanced Key Usage”) se guarda cual va a ser el destino del certificado, por ejemplo para autenticación del cliente. Estas extensiones están en la colección Extensions del certificado, y para obtener la información almacenada debe castearse según el tipo del mismo. Para saber qué tipo de extensión es la almacenada se puede leer la propiedad Oid, la cual devuelve la clase homónima que representa un identificador de un objeto criptográfico (cryptographic object identifier) y luego, de este objeto, podemos leer la propiedad FriendlyName para obtener el nombre de la extensión. A continuación hay un código de ejemplo donde se muestra la información de un certificado:
240
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Diagnostics; namespace CertDigitales { class Program { static void Main(string[] args) { X509Certificate2 objCert1; //X509Certificate2 objCertB; X509Store objStore; objStore = new X509Store(StoreName.Root, StoreLocation.LocalMachine); objStore.Open(OpenFlags.ReadOnly); foreach (X509Certificate2 objCertB in objStore.Certificates) { Console.WriteLine(objCertB.SubjectName.Name); if (objCertB.SubjectName.Name == "CN=Microsoft Root Certificate Authority, DC=microsoft, DC=com") { StringBuilder objSB = new StringBuilder("Detalle del certificado: \n\n"); //Detalle objSB.AppendLine("Persona = " + objCertB.Subject); objSB.AppendLine("Emisor = " + objCertB.Issuer ); objSB.AppendLine("Válido desde = " + objCertB.NotBefore.ToString()); objSB.AppendLine("Válido hasta = " + objCertB.NotAfter.ToString()); objSB.AppendLine("Tamaño de la clave = " + objCertB.PublicKey.Key.KeySize.ToString()); objSB.AppendLine("Número de serie = " + objCertB.SerialNumber); objSB.AppendLine("Hash = " + objCertB.Thumbprint); //Extensiones objSB.AppendLine("\nExtensiones:\n"); foreach (X509Extension objExt in objCertB.Extensions) { objSB.AppendLine(objExt.Oid.FriendlyName + " (" + objExt.Oid.Value + ')'); if (objExt.Oid.FriendlyName == "Key Usage") { X509KeyUsageExtension ext = (X509KeyUsageExtension)objExt; objSB.AppendLine(" " + ext.KeyUsages); } if (objExt.Oid.FriendlyName == "Basic Constraints") { X509BasicConstraintsExtension ext = (X509BasicConstraintsExtension)objExt; objSB.AppendLine(" " + ext.CertificateAuthority); objSB.AppendLine(" " + ext.HasPathLengthConstraint); objSB.AppendLine(" " + ext.PathLengthConstraint); } if (objExt.Oid.FriendlyName == "Subject Key Identifier") { X509SubjectKeyIdentifierExtension ext = (X509SubjectKeyIdentifierExtension)objExt; objSB.AppendLine(" " + ext.SubjectKeyIdentifier); } if (objExt.Oid.FriendlyName == "Enhanced Key Usage") //2.5.29.37 { X509EnhancedKeyUsageExtension ext = (X509EnhancedKeyUsageExtension)objExt; OidCollection objOids = ext.EnhancedKeyUsages; foreach (Oid oid in objOids) objSB.AppendLine(" " + oid.FriendlyName + " (" + oid.Value + ')');
241
} } Console.WriteLine (objSB.ToString()); } } Console.ReadKey(); } } }
Cómo no contamos con un certificado digital de alguna empresa he usado este de Microsoft (CN=Microsoft Root Certificate Authority, DC=microsoft, DC=com).
2.10.4 Encriptación y Desencriptación Utilizando un Certificado (Este no es posible a menos que ustedes tengan uno en su empresa o tengan un token instalado en su computador).
Para encriptar y desencriptar datos se necesita la siguiente librería (using System.Security.Cryptography.Pkcs;), por alguna razón en C Sharp no quiso funcionar, por consiguiente cree un proyecto usando código Visual Basic y a continuación ingrese el siguiente código. Imports Microsoft.VisualBasic Imports System.Data Imports System.Collections.Generic Imports System Imports System.Linq Imports System.Text Imports System.Security.Cryptography.X509Certificates Imports System.Diagnostics Imports System.Security.Cryptography Imports System.Security.Cryptography.Pkcs Imports Manifiesto.WS.ManifiestoService Imports Manifiesto.WS.WSManifiesto Partial Class _Default Inherits System.Web.UI.Page Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Dim objCertB As X509Certificate2 Dim objStore As New X509Store objStore = New X509Store(StoreName.Root, StoreLocation.LocalMachine) objStore.Open(OpenFlags.ReadOnly) For Each objCertB In objStore.Certificates If objCertB.SubjectName.Name = "CN=Certificado Empresarial Clase‐A, O=Certicamara S.A. Entidad de Certificacion, L=Carrera 9 16‐21 Bogota, C=CO" Then Dim objContent As ContentInfo = New ContentInfo(Encoding.ASCII.GetBytes("Fredys Simanca")) Dim objEncryptedData As EnvelopedCms = New EnvelopedCms(objContent) Dim objRecipient As CmsRecipient = New CmsRecipient(objCertB) objEncryptedData.Encrypt(objRecipient) Dim bytResult As Byte() = objEncryptedData.Encode() Response.Write(bytResult.ToString) End If Next End Sub End Class
242
He usado un certificado digital de Certicamara para ilustración del ejemplo. El siguiente es el código para el proceso de desencriptado. 'desencriptando objEncryptedData = New EnvelopedCms() objEncryptedData.Decode(bytResult) objEncryptedData.Decrypt() Dim bytDoc As Byte() = objEncryptedData.ContentInfo.Content Response.Write("Datos desencriptados: " + Encoding.ASCII.GetString(bytDoc)) En total quedaría así: Imports Microsoft.VisualBasic Imports System.Data Imports System.Collections.Generic Imports System Imports System.Linq Imports System.Text Imports System.Security.Cryptography.X509Certificates Imports System.Diagnostics Imports System.Security.Cryptography Imports System.Security.Cryptography.Pkcs Imports Manifiesto.WS.ManifiestoService Imports Manifiesto.WS.WSManifiesto Partial Class _Default Inherits System.Web.UI.Page Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Dim objCertB As X509Certificate2 Dim objStore As New X509Store objStore = New X509Store(StoreName.Root, StoreLocation.LocalMachine) objStore.Open(OpenFlags.ReadOnly) For Each objCertB In objStore.Certificates If objCertB.SubjectName.Name = "CN=Certificado Empresarial Clase‐A, O=Certicamara S.A. Entidad de Certificacion, L=Carrera 9 16‐21 Bogota, C=CO" Then Dim objContent As ContentInfo = New ContentInfo(Encoding.ASCII.GetBytes("Fredys Simanca")) Dim objEncryptedData As EnvelopedCms = New EnvelopedCms(objContent) Dim objRecipient As CmsRecipient = New CmsRecipient(objCertB) objEncryptedData.Encrypt(objRecipient) Dim bytResult As Byte() = objEncryptedData.Encode() Response.Write(bytResult.ToString) 'desencriptando objEncryptedData = New EnvelopedCms() objEncryptedData.Decode(bytResult) objEncryptedData.Decrypt() Dim bytDoc As Byte() = objEncryptedData.ContentInfo.Content Response.Write("Datos desencriptados: " + Encoding.ASCII.GetString(bytDoc)) End If Next End Sub End Class