Facultad de Estudios Tecnológicos

1


UNIVERSIDAD DON BOSCO
FACULTAD DE ESTUDIOS TECNOLÓGICOS
ESCUELA DE COMPUTACIÓN



CICLO: 02/2013
GUÍA DE LABORATORIO #10
Nombre de la Práctica: ADO .NET y conexiones a Base de Datos. Parte II
Lugar de ejecución: Centro de computo
Tiempo estimado: 2 horas con 30 minutos
MATERIA: Lenguaje de Programación I




I. OBJETIVOS

Qué el estudiante:
Presentar conjuntos de datos específicos de una BDD en una aplicación.
Filtrar datos presentados al usuario por medio de la transferencia de parámetros a una consulta SQL
de selección.

II. INTRODUCCIÓN TEÓRICA.


ADO.NET
ADO.NET es la tecnología de acceso a datos utilizada por Visual Studio .NET y por el resto de
aplicaciones del .NET Framework. Forma parte integral de .NET Framework, y proporciona acceso a
datos relacionales, datos XML y datos de aplicaciones.
ADO.NET utiliza un modelo de acceso pensado para entornos de datos desconectados. Esto quiere decir
que la aplicación se conecta al origen de datos, hace lo que debe de hacer, por ejemplo seleccionar
registros, los carga en memoria y se desconecta del origen de datos.
La arquitectura ADO.NET permite crear componentes que administran eficientemente datos procedentes de
múltiples orígenes, y también proporciona las herramientas necesarias para solicitar, actualizar y reconciliar
datos entre grupos de aplicaciones.

Componentes de ADO.NET

Usted necesita desarrollar 3 pasos mínimos para acceder a sus datos almacenados:
1. Acceder al Origen de Datos y mostrar los datos en el formulario o Web
2. Manipular los Datos
3. Retornar los datos modificados para actualizar la base de datos

ADO.NET es un conjunto de clases que usted utiliza para acceder y manipular orígenes de datos como
por ejemplo, una base de datos en SQL Server o una planilla en Excel o una base de datos Access, etc.
Utiliza XML como el formato para transmitir datos desde y hacia su base de datos y su aplicación Web.
El modelo de objetos ADO.NET provee una estructura de acceso a distintos orígenes de datos. Esta
estructura de acceso tiene 2 componentes principales:
A) Un Proveedor de Datos .NET b) Un objeto de la clase DataSet.
Facultad de Estudios Tecnológicos
2

Objeto

Descripción
Clase para origen SQL
Server
Clase para un origen
OLEDB
Connection Establece una conexión a un
origen de datos determinado.
SqlConnection OleDBConnection

EL PROVEEDOR DE DATOS .NET
Permite el enlace entre el Origen de Datos y un objeto DataSet. Un proveedor de datos de .NET
Framework es el que se conecta a una base de datos, ejecuta comandos y recuperara resultados. Esos
resultados se procesan directamente o se colocan en un DataSet de ADO.NET con el fin de exponerlos al
usuario para un propósito específico, junto con datos de varios orígenes, o de utilizarlos de forma remota
entre niveles.
Para comenzar, usted debe determinar un origen de datos y luego seleccionar el proveedor de .NET
adecuado
a) Un Origen de Datos es el deposito de datos al cual necesita enlazar a su aplicación .NET, por
ejemplo: una Base de datos (Ejemplo: Access, SQL Server, Oracle) o también datos personalizados en
archivos XML u otros formatos.

b) Espacios de nombres (Namespace) para manejo de datos en el .NET Framework: Para tener
acceso a las diversas clases de acceso a datos de un proveedor específico, debe importar a sus
formularios el espacio de nombres System.Data el cual contiene diversos espacios de nombres
con clases especializadas de acuerdo al proveedor de datos que desee acceder por medio de su
aplicación
Entre los espacios de nombres de .NET Framework relativos a datos y XML incluidos en el namespace
Data tenemos:

System.Data.OleDb
Clases que componen el proveedor de datos de .NET Framework para orígenes de datos
compatibles con OLE DB. Estas clases permiten conectarse a un origen de datos OLE DB, ejecutar
comandos en el origen y leer los resultados.
System.Data.ODBC
Clases para conectarse a orígenes de datos compatibles con ODBC.
System.Data.Xml
Clases que proporcionan funcionalidad basada en estándares para procesar código XML.
System.Data.SqlClient
Clases que conforman el proveedor de datos de .NET Framework para SQL Server, que
permite conectarse a un origen de datos SQL Server 7.0, ejecutar comandos y leer los resultados. El
espacio de nombres System.Data.SqlClient es similar al espacio de nombres System.Data.OleDb,
pero optimizado para el acceso a SQL Server 7.0 y versiones posteriores.
System.Data.SqlTypes
Proporciona clases para tipos de datos nativos de SQL Server. Estas clases ofrecen una alternativa
más
segura y más rápida a otros tipos de datos. System.Data.OracleClient
Clases que componen el proveedor de datos de .NET Framework para Oracle. Estas clases permiten
el
acceso a orígenes de datos Oracle en el espacio administrado.
Clases de objetos provistos por los proveedores de datos .NET
Existen 5 clases de objetos fundamentales del modelo de acceso a datos proporcionados por cada
proveedor de datos. Los objetos generales Connection, DataAdapter, DataReader, Command y
Parameter son integrados dentro del .NET Framework. Cada proveedor de la tabla anterior define las
clases que definen a estos objetos.
Por ejemplo, en la tabla siguiente se muestra una descripción de estas clases generales y los nombres de
clases de objetos para el proveedor de OLEDB y de SQL Server:
Facultad de Estudios Tecnológicos
3

DataReader Lee una secuencia de datos de
sólo avance y sólo lectura desde
un origen de datos
SqlDataReader OleDBDataReader
DataAdapter Llena un DataSet y realiza las
actualizaciones necesarias en el
origen de datos
SqlDataAdapter OleDBDataAdapter
Command Ejecuta un comando SQL en un
origen de datos
SqlCommand OleDBCommand
Parameter Cuando ejecuta un comando el
cual requiere que definan
argumentos, los objetos de la
clase Parameter permiten definir
el nombre y valor de cada uno
de estos parámetros que se
envían desde la aplicación por
medio de un objeto Command
SqlParameter OleDBParameter


Configuración de un objeto Command
Cuando ha establecido una conexión, muchas veces será necesario ejecutar instrucciones SQL para
realizar actualizaciones a los registros de las tablas o también ejecutar funciones almacenadas en la BDD.
Los objetos de la clase Command permiten definir la funcionalidad de una instrucción SQL dentro de
ADO.NET, por medio de la asignación de sus propiedades, las cuales son:

Propiedades del objeto Command
Propiedad Descripción Valores aceptados por la propiedad
Connection Nombre de Objeto de una
conexión activa
Variable objeto de la clase Connection la cual este
actualmente abierta
CommandText Almacena el texto del comando a
ejecutar por el origen Este se
redacta en formato SQL
String con la sentencia SQL que desea que ejecute
la BDD enlaza por la conexión activa
CommandType Indica como debe interpretarse el
texto de la instrucción SQL.
Text: valor predeterminado. Se usa solo para
instrucciones que administren registros, por
ejemplo: select, insert y delete
StoredProcedure: para instrucciones que
activan/ejecutan funciones almacenadas en el
origen de datos.
TablaDirect: Equivale a ejecutar la consulta SQL
SELECT * FROM nombretabla, y nombretabla es el
nombre de una tabla especificada en
CommandText

Usted puede asignar las propiedades CommandText y CommandType, pero el comando solo se ejecutara
cuando establezca un objeto Connection a la primera propiedad, el cual también debe esta abierto .


OBJETOS PARAMETER: Agregando parámetros a un objeto Command
La mayoría de procedimientos almacenados en un origen de datos y algunas consultas SQL poseen uno o
mas parámetros. Estos parámetros son útiles en los procedimientos almacenados ya que funcionan igual
que en una función de VB.
Facultad de Estudios Tecnológicos
4
Ejemplos de instrucciones que necesitan argumentos (los cuales se muestran resaltados):
EJEMPLO: Instrucción SQL y significado
select * from Mitablita where TotalVentas>20

Es una instrucción de consulta que permite seleccionar de la tabla Mitablita solo los registros que
cumplan que el valor del campo TotalVentas sea mayor que 20. El argumento en este caso es una
condición que relaciona el nombre de un campo y su valor(20).
update Mitablita SET Nombre=‟Sara‟ where IdCliente=12

Similar a la instrucción anterior, pero ahora solo actualizara el valor del campo Nombre en todos los
registros que tengan en su campo IdCliente el valor (12).
Suponga que tiene una BDD almacenada en un servidor SQL Server. Dentro de la BDD define a un
procedimiento llamado miProcedimiento con estas instrucciones:
CREATE PRECEDURE miProcedimiento
@miDato char(11)
AS
SELECT * FROM otraTabla T where Nombre=@miDato

Observe que el procedure tiene un argumento llamado @miDato el cual es de tipo char de 11 caracteres y
se utiliza dentro de la definición del mismo para evaluar una condición dentro de una consulta Select

Retornando a .NET, suponga que quiere ejecutar una instrucción SQL que permita ejecutar este
procedure almacenado en el servidor desde una conexión SqlClient. Si crea un objeto Command, le puede
asignar el valor siguiente a su propiedad CommandText:

miProcedimiento 'Norma'

Con esta instrucción se quiere ejecutar al procedimiento almacenado miProcedimiento, enviando un
argumento con el valor de „Norma‟

Para que un objeto Command pueda manejar los parámetros (con su respectivo valor) en una instrucción
SQL que los necesite para ejecutarse, este solo necesita el nombre del procedimiento almacenado a
ejecutar y cada parámetro que requiera, porque el cuerpo de instrucciones las ejecuta la BDD.

Para estos casos, un objeto Command posee una colección de Objetos Parameter. Y cada objeto Parameter
consta de las siguientes propiedades mínimas con las que se le definen a cada parámetro que necesite una
instrucción SQL:

Propiedad Descripción Ejemplo:
Observe el ultimo ejemplo de los objetos
Parameter
Name El nombre del parámetro del procedimiento @miDato
Type El tipo de datos del parámetro String
Length tamaño del tipo de dato 11
Direction El uso del parámetro, si será de envío a la BDD
(Input) o retornado de la BDD (Output)
Input
Value Valor a usar en la consulta generado desde
VB.NET
Norma

Cada parámetro se agrega a la colección Parameters de un objeto Command por medio del metodo Add.
Facultad de Estudios Tecnológicos
5
Ejemplo: de nuevo observe el ejemplo del procedimiento almacenado (miProcedimiento) y analice como
se define un comando para ejecutar el procedimiento almacenado, luego se crea un parámetro y asigna el
valor “Norma”, y por ultimo como incluye este Parameter a un comando con el uso del metodo Add:

'Cree un enlace hacia la BDD Northwind dentro del servidor SQL local, y con usuario “sa”
Dim Conex as New SqlConnection(“Data Source=(local);
Initial Catalog=Northwind;User id=sa”)
Dim cmd As New SQLCommand
Dim pm As SqlParameter

Conex.Open() 'Activo la conexion

'Configuro el comando para llamar al procedimiento almacenado miProcedimiento
cmd.CommandType=CommandType.StoredProcedure
cmd.CommandText= “miProcedimiento”
cmd.Connection= Conex „Enlazo a un objeto Connection que esta abierto

'Creo y configuro un parametro que necesita proc miProcedimiento
pm =new SqlParameter
With pm
.Name=”@miDato”
.Type=SqlDbType.Char
.Length=11
.Direction=ParameterDirection.Input
'Valor que tomara dicho parámetro para que el proc miProcedimiento funcione
.Value=”Norma”
End With

'Agrego el parámetro pm configurado anterior al objeto cmd con el metodo add
cmd.Parameters.Add(pm)

Es de aclarar que muchas de las propiedades de ADO.NET tienen la habilidad de interpretar cada
parámetro con solo saber las propiedades Name y Value. Asi que el With usado para objeto pm anterior
puede ser simplificado a una de estas formas:
FORMA 1
With pm
.Name=”@miDato”
.Value=”Norma”
End With

cmd.Parameters.Add(pm)

FORMA 2
pm.Name=”@miDato”
pm.Value=”Norma”
FORMA 3

Tambien puede crear un objeto Parameter solo al momento de llamar al
método Add de la colección Parameters. Aquí le declara las 2
propiedades mínimas por medio de su constructor así:

„Agrego un parámetro al Command cmd
cmd.Parameters.Add(New SqlParameter(“@miDato”,”Norma”))

Ejemplo:
Definiendo un Objeto OleDBCommand con dos parámetros. Observe con mucho cuidado los cambios con
el ejemplo anterior al momento de escribir el comando SQL dentro del Command de OLEDB

Dim conexOle As New OleDBConnection (“Provider=Microsoft.Jet.OLEDB.4.0;
Data Source=C:\miBDD.mdb”)
Facultad de Estudios Tecnológicos
6
Metodos para Ejecutar una instrucción SQL dentro del Objeto Command
ExecuteNonQuery : ejecuta una instrucción SQL que no devuelve registros, entonces puede ser una
instrucción Delete, Update o Insert, También se usa si el procedimiento almacenado solo devuelve
salidas a través de parámetros.
ExecuteReader : Ejecuta instrucción y devuelve un objeto SqlDataReader que contiene los registros
resultantes de la consulta SQL del Command
ExecuteScalar : se usa cuando hay que devolver un solo valor (columna) de datos de una instrucción SQL
Select
ExecuteXMLReader : solo es permitido para un Command del proveedor SQL Server (Clase
SQLCommand). Es parecido a ExecuteReader, pero devuelve un XMLReader

ConexOle.Open()

'cree un objeto Command con dos parámetros, cuyos valores se presentan como ( ? )
Dim cmdOle As New OleDb.oledbcommand(“select * from Tabla
where Ciudad = ? and Region = ?”)

'agregue un objeto Parameter para sustituir al primer parámetro (@ciudad)
Dim paramOle As OleDb.OleDbParameter=cmdOle.Parameters.Add(“@Ciudad”,
OleDb.OleDbType.Varchar, 30)
paramOle.value=”San Luis” „Valor asignado a param desde aplicac (no desde la BDD)

'agregue otro objeto parámetro para sustituir el Segundo parametro (@region)
paramOle= cmdOle.Parameters.Add(“@region”,OleDb.OleDbType.Varchar, 2)
paramOle.value=”Oriente”

'Ejecute el command y almacene datos devueltos en un OleDataReader
Dim oleDataReader As OleDb.OleDbDataReader= cmdOLe.ExecuteReader
(CommandBehavior.CloseConnection )

'Muestra el resultado de la primera columna de cada una de filas en secuencia
While oleDataReader.Read
Msgbox(oleDataReader.Getvalue(0).ToString())
End while

'Cierra el lector de datos y la conexión
oleDataReader.Close()
ConexOle.Close()


Elegir un método para ejecutar el Command
Después de haber configurado las propiedades de un objeto Command (incluyendo los parámetros
cuando los necesite), es posible ejecutarlo llamando a uno de sus métodos de ejecución que se listan a
continuación:














Existen diversos métodos de ejecución para así optimizar los tipos de instrucciones SQL disponibles, y
usted debe seleccionar el método que mas se ajuste a sus necesidades.

Ejemplo:
Suponga que desea borrar un conjunto de registros de una tabla llamada Empleados de una BDD por
medio de la instrucción SQL DELETE. El segmento que realiza esta tarea es la siguiente:

Dim TextoSql As String
Facultad de Estudios Tecnológicos
7
Dim TotFilasBorradas As Integer
Dim valor As String = “Juan”

Dim cmd as New SqlCommand( )
TextSql=”Delete from Empleados where MiCampo= '“+valor+”'”
'Configuro el objeto command
With cmd
.Connection= ObjetoConex „Asumo que este objeto es un Connection que
esta abierto
.CommandText=TextSql
End With

'Ejecuto la instrucción Delete del objeto Command
TotFilasBorradas = cmd.ExecuteNonQuery()

'Muestro total de filas que fueron borradas en la BDD
Msgbox( TotFilasBorradas.ToString )



Usar los lectores de datos DataReader y DataSet
Cuando ejecuta una consulta SELECT o un procedimiento almacenado que devuelve registros, es
necesario utilizar un método de ejecución que le permita acceder a estos registros. Un objeto Command
puede ejecutar instrucciones SQL que devuelvan conjuntos de registros por medio de los métodos de
ejecución ExecuteReader.
.El método ExecuteReader devuelve un objeto DataReader, pero este no puede funcionar de un modo
desconectado porque esta clase esta hecha para extraer los registros de una BDD lo mas rápido posible
para procesarlos secuencialmente (solo en una dirección), por lo que la capacidad de desplazamiento esta
limitada al movimiento hacia delante de los registros obtenidos.

Un DataReader consta de los métodos siguientes para leer valores de cada registro y/o campo:

Metodo de DataReader Descripción
Read Método que coloca un señalizador(posición del registro actual) en el próximo
registro a leer por el DataReader
Item(Indice o nombre) Propiedad que devuelve el valor de un campo especifico de los datos ya sea
por un entero(Índice) o sino un string del nombre de un campo
GetName Función que devuelve el nombre de una columna/campo de los datos
Metodos varios Get Son un conjunto de funciones que inician con las letras Get. Estas devuelven
valor de un campo (con un índice) en un tipo de dato específico (como String,
Entero, Decimal, etc). Ejemplos de estas funciones: GetString, GetBoolean,
GetDouble y otras mas
FieldCount Función que devuelve numero de columnas/campos de los datos recibidos
IsDBNull Función que permite saber si hay un valor Null en una columna de los datos

Facultad de Estudios Tecnológicos
8

OBJETO DATAADAPTER
Los objetos de la clase DataAdapter proporcionan los medios para que los objetos del DataSet puedan
interactuar con una BDD. Un objeto DataAdapter proporciona el esquema de asociación completo de la
BDD al formato XML según el objeto DataSet; tambien asocia el XML devuelto por un DataSet a los
objetos Insert, Update y Delete, y establece todos los parámetros en consecuencia.

Un DataAdapter permite albergar cuatro objetos Command de ADO.NET. Cada uno de estos comando
contiene las instrucciones/parámetros SQL necesarios para realizar una de las 4 acciones SQL principales
sobre una BDD: Select, Insert, Update y Delete.
Entonces un objeto DataAdapter presenta estos 4 command como propiedades llamadas:
SelectCommand, InsertCommand, UpdateCommand y DeleteCommand. El programador puede
configurar previamente estos cuatro objetos Command para obtener control absoluto sobre un conjunto
concreto de interacciones con una BDD.


OBJETO DATASET
Es el segundo componente fundamental de la arquitectura de ADO.NET. Después de que usted establece
una conexión con una Base de Datos por medio de un proveedor, puede acceder entonces a sus datos por
medio de objetos de la clase DataSet.

Un DataSet guarda la información recibida desde una conexión y trabaja en un entorno desconectado, esto
significa que los datos en un DataSet pueden ser manipulados sin necesidad que el formulario mantenga
una conexión “permanente” con el origen de datos. La conexión solo se reestablece cuando usted necesita
actualizar cambios. Este puede contener datos de múltiples tablas, sus campos y además las relaciones-
restricciones que las asocian entre si.

Prácticamente un DataSet viene a ser una caché de memoria interna de datos recuperados de un origen de
datos o algo así como una BDD portátil.

Ahora aprenderá como colocar registros de una BDD en un objeto DataSet, modificarlos y por ultimo
enviar los cambios hechos en los datos de un DataSet a la BDD.


Presentacion de DataAdapter
Para poder tranferir registros a y desde un DataSet, es necesario utilizar un objeto de la clase
DataAdapter. Un DataAdapter es un adaptador de datos que permite establecer un puente entre un
origen de datos y un objeto DataSet.
Un DataAdapter difiere de las clases Command explicadas antes porque un Command se comporta como
una “funcion” que devuelve registros.
En cambio un DataAdapter posee varias propiedades que representan objetos de Command individuales,
los cuales son: SelectCommand, UpdateCommand, InsertCommand y DeleteCommand. Un
DataAdapter transfiere los registros de una BDD utilizando los comandos mencionados.

En general, la preocupación principal de un DataAdapter consiste en saber como se asignan los datos a
y desde una BDD origen.



Recuperando registros hacia un DATASET
Un control DataAdapter consta de una serie de métodos con los cuales puede recuperar/enviar
información desde/hacia un Origen de datos especifico. Entre los métodos más importantes tenemos:
Facultad de Estudios Tecnológicos
9
Jerarquia Clase Descripción de la clase
1 Tables Acceso a una de las tablas dentro de los resultados de un DataSet
2 Column Define las caracteristicas de cada campo obtenido de la consulta SQL
aplicada. Estas características pueden ser: Tipo de dato, Si puede o no tener
valor nulo(vacio), si es autonumérico (devolviendo el valor inicial del conteo,
incremento y ultimo valor utilizado en los registros)
3 Rows Contiene el conjunto de registros individuales(Filas) que le pertenecen a una
tabla especifica
3 Item Almacenan los valores individuales de los campos del registro seleccionado

Metodo Fill: permite recuperar registros de una BDD y así rellenar un DataSet con los registros
resultantes de una consulta a una BDD o sino de una fuente XML.
El método Fill tiene varias sobrecargas, de las cuales la más usada solicita el objeto DataSet que guarde
los datos recuperados y un String que indique el nombre del DataTable interior que tendrá los datos. Este
último por lo general es el nombre de la tabla

Metodo FillSchema: se usa para configurar un objeto DataTable situado dentro de un objeto DataSet con
el esquema de la BDD e información restringida antes de completar el objeto DataTable mediante el
DaraAdapter.
Por ejemplo, el objeto DataTable debe conocer información restringida asignada por la BDD como la
clave principal o campos autonuméricos de una tabla, para poder actualizar o eliminar información de
forma adecuada.
Este método FillSchema se basa en la instrucción SQL indicada en el objeto SelectCommand para
obtener la información de esquema específica de la BDD.


Como acceder a los valores de los campos de una tabla
Acceder a los registros individuales de un DataSet rellenado es distinto a acceder ellos por medio de un
DataReader, ya que no existe un registro activo ni método de movimiento asociado.

En su lugar, se utilizan colecciones de objetos hijos dentro de un DataSet que permiten organizar las tablas,
filas y los valores de cada campo de los resultados de datos almacenado en el DataSet.
Las clases de estos objetos incluidos dentro de un DataSet que permiten manejar los registros de una o
más tablas están organizados en una jerarquía dentro de un objeto DataSet. Las clases y su jerarquía son
las siguientes:













Todas las clases anteriores se manejan como “arreglos de objetos” ya que debe utilizarse un índice entero
para saber a cual objeto de la colección se refiere al programarlo.

Ejemplo:
Si por ejemplo se tiene un DataSet llamado DStabla. Con la instrucción siguiente se mostraría el valor del
quinto campo del segundo registro(fila) de la primera tabla almacenada en el DataSet:

Msgbox (DStabla.Tables(0).Rows(1).Item(4).ToString)

Observe que el conteo entero para referirse a un objeto en particular comienza con 0 (al igual que como se
maneja los índices de los arreglos en lenguaje C, Java y otros).
Facultad de Estudios Tecnológicos
10
Ejemplo:
También podría usar identificadores con nombres (en lugar de enteros) para facilitar el desplazamiento,
así por ejemplo:

With DStabla.Tables(0)
For i=0 To .Rows.Count-1
MsgBox(.Rows(i).Item(“Campo2”))
Next
End With

El código anterior imprime en pantalla el valor del campo llamado Campo2 de cada una de las filas de la
primer tabla dentro del DataSet DSTabla.




Como cargar múltiples tablas desde una conexión

Dentro de un DataSet puede colocar los registros de dos o más tablas e incluso establecer las relaciones
(uno a uno, uno a varios) entre ellas. Puede hacer esto de dos formas diferentes:
1. llamar al método Fill de un DataAdapter sobre múltiples objetos DataAdapter utilizando el
mismo DataSet como argumento de Fill.
2. Ejecutar un procedimiento almacenado con más de una instrucción SELECT, En este caso solo
bastara un solo objeto DataAdapter.

Como agregar restricciones y relaciones
Además de almacenar tablas, un objeto DataSet tiene la capacidad de almacenar relaciones y restricciones
como lo hace la BDD. Dado que es posible modificar los datos de un DataSet mientras se esta
desconectado de la BDD, el administrador de la BDD no estará presente para exigir las restricciones como
por ejemplo: los campos únicos y las llaves principales.

Ejemplo:
El código siguiente muestra un nuevo objeto, el objeto DataColumn, que representa un campo de una
tabla de datos. Es posible establecer la propiedad Primary Key de cada tabla dentro de un DataSet a una
matriz de estas columnas, con el fin de definir la clave principal. La columna SSN es la clave principal de
la tabla Person. Las columnas SSN y Dept forman conjuntamente la clave principal de la tabla Emp loyee.
SSN también es una clave externa de la tabla Employee, por lo que, con el fin de mantener la integridad
de la BDD, habría que eliminar un registro de la tabla Employee si la persona correspondiente fuera
eliminada de la tabla Person. Creando un objeto ForeignKeyConstraint, podemos garantizar que esto se
realiza de forma automática.

'configura los objetos de columna para un acceso mas sencillo
Dim colSSNP, colSSNE as DataColumn
colSSNP=dsMain.Table(“Person”).Columns(“SSN”)
colSSNE=dsMain.Table(“Employee”).Columns(“SSN”)

„Crea las claves principales
Dim arPersKey(1) as DataColumn
Dim arEmplKey(2) as DataColumn

arPersKey(0)=colSSNP arEmplKey(0)=colSSNE
arEmplKey(1)=dsMain.Tables(“Employee”).Columns(“Dept”)
Facultad de Estudios Tecnológicos
11
dsMain.Tables(“Person”).PrimaryKey=arPersKey
dsMain.Tables(“Empleyee”).PrimaryKey=arEmplKey

'Crea la clave externa para eliminación en cascada
Dim fkSSN As ForeignKeyConstraint
fkSSN=new ForeignKeyConstraint(“SSNForKey”,colSSNP,colSSNE)
fkSSN.DeleteRule=Rule.Cascade
dsMain.Tables(“Empleyee”).Constraints.Add(fkSSN)

Si muestra estos datos en 2 dataGrid (uno por cada DataSet) vera que si elimina un registro de la tabla
Person, desaparecerá el correspondiente registro o registros de la tabla Employee, debido a la restricción
de la llave primaria.


Como mostrar el contenido de un DataSet
El concepto de enlace de datos implica asociar un formulario con un campo o una tabla de datos. El
control maneja el desplazamiento, las actualizaciones y las eliminaciones, por lo que no será necesario
escribir código para actualizar los registros del DataSet que están enlazados a el.
En el entorno de datos desconectados que utiliza ADO.NET los controles enlazados a datos no se
comunican directamente con la BDD, sino que lo hacen con los datos de un DataSet local.
Ejemplos de enlace de un DataGrid:
Ejemplo 1:
Grid1.DataSource= nombreDataSet
'Especifica nombre de una de las tablas almacenada en DataSet anterior.
Grid1.DataMember=”NombreTabla1”
Grid1.CaptionText =”NombreTabla1”

Ejemplo 2:
'borra el enlace activo
Grid1.DataMember=””
Grid1.DataSource=Nothing


Como filtrar la visualizacion de las filas
En el grid anterior, se ha asignado el objeto DataTable a la propiedad DataMember del Grid, y muestra
cada registro de la tabla con todas las opciones de edición posibles. Sin embargo, a veces solo será
necesario mostrar ciertas filas o prohibir a los usuarios que modifiquen su contenido.
Un filtro permite determinar que registros de una tabla van a ser visibles y que restricciones de acceso
asignarle. Es similar a una clausula WHERE de SQL.

Ejemplo:

With DataSet1.Tables(“Person”)
.DefaultView.RowFilter=”NombreCampo Like „ ”+”Norma”+” %‟ ”
.DefaultView.AllowDelete =False
.DefaultView.AllowEdit =False
Facultad de Estudios Tecnológicos
12
.DefaultView.AllowNew =False

Grid1.DataSource= .DefaultViuw
En with

Grid1.CaptionText= “Filtrado en el ultimo nombre”


Como verificar los registros modificados

Un objeto DataTable contiene múltiples objetos DataRow, cada uno de los cuales representa un registro de
la tabla. Puede modificar el contenido del DataSet o bien cambiar los valores de un objeto DataRow en
especial, o bien utilizar un Grid enlazado.

Una característica interesante de la clase DataSet es la capacidad de saber que filas han sido modificadas.
Esto es importante, ya que el DataSet se encuentra desconectado de su BDD, así que deberá saber si ha
habido adición, eliminación o actualización de filas, para que los cambios puedan ser enviados a una
BDD. Por ejemplo si una tabla tiene 1000 registros y usuario solo modifica 12 filas, será mejor que solo se
envié el listado de solamente estas filas modificadas y así no saturar a la BDD con actualizaciones
innecesarias.
Para manipular los cambios de un DataSet, este consta de los siguientes métodos y propiedades:

RowState : determina los cambios realizados en una fila
GetChanges : devuelve un nuevo objeto DataSet que solo contiene las filas modificadas
AcceptChanges : coloca todos los cambios en el DataSet activo, restableciendo la propiedad RowStare
RejectChanges: deshace los cambios en el DataSet y lo retorna al estado de la versión original, o la
versión que hacia desde la ultima llamada a AcceptChanges.


Como actualizar los registros en una BDD
El paso final de la interacción entre los objetos DataAdapter y DataSet es el método Update del primer
objeto mencionado. Este método acepta el objeto DataTable como parámetro y se repite a través de cada
objeto DataRow del objeto DataTable. El metodo DataTable establece la asociación de cada fila del objeto
DataTable con el método Insert, Update o Delete adecuado en función del estado de la fila.

Esencialmente, el método Update se encarga de procesar en lotes la actualización de los datos en una sola
invocación. Puede trabajar sobre un conjunto de datos sin conexión dentro de un DataSet y propagar
todos sus cambios a la BDD mediante objetos Command preconfigurados con una sola invocación al
metodo Update del objeto DataAdapter apropiado.

Ejemplo 1:
Configuración de un objeto DataAdapter mediante la asociación manual de objetos
Command
'Cree objeto connection
Dim oconnection as new sqlclient.sqlconnection(“CADENA CONEXION”)
Oconnection.open()

'cree un adaptador de datos vacio
Dim oDataAdapter as new sqlclient.sqldatadapter()

'cree una instruccion Select
Facultad de Estudios Tecnológicos
13
Dim oselectcommand as new sqlclient.sqlcommand(“select ClienteID, nombreEmpresa,
NombreContacto from Clientes”, oconnection)

'cree una instrucción Insert y añada los parámetros adecuados
Dim oInsertCommand as new SqlClient.sqlcommand(“insert into Clientes( NombreEmpresa,
NombreDeContacto) values (@NombreEmpresa,@NombreDeContacto)”,oconnection)

oInsertcommand.parameters.add(new
sqlclient.sqlParameters(“@@NombreEmpresa”,system.data.sqldbtype.NVarChar, 20,
System.Data.ParameterDirection.Input, True, Ctype(0,Byte), Ctype(0,Byte),
”NombreEmpresa”, System.DataRowVersion.Current, Nothing))

oInsertcommand.parameters.add(new
sqlclient.sqlParameters(“@NombreDeContacto”,system.data.sqldbtype.NVarChar, 20,
System.Data.ParameterDirection.Input, True, Ctype(0,Byte), Ctype(0,Byte),
”NombreDeContacto”, System.DataRowVersion.Current,Nothing))

'cree una instruccion Update y añada los parametros adecuados
Dim oupdatecommand as new sqlclient.sqlcommand( “update clientes set NombreEmpresa=
@NombreEmpresa, NombreDeContacto=@nombreDeContacto where ClienteID=
@ClienteID”, oconnection)

Oupdatecommand.parameters.add( new sqlclient.sqlparameter ( “@NombreDeContacto”,
system.data.sqltype.nvarchar, 20, system.data.parameterdirection.input, true,
ctype(0,byte), ctype(0,byte), ”NombreDeContacto”, system.data.datarowversion.current,
nothing) )
Oupdatecommand.parameters.Add( New sqlcliente.sqlparameters( “@ClientID”,
system.data.sqldbtype.int,
5,system.data.parametersdirection.input,true,ctype(0,byte),ctype(0,byte), ”ClienteID”,
system.data.datarowversion.Current, Nothing) )

'Creo el comando delete con el parámetro (ClienteID) unicamente
Dim odeletecommand as new sqlclient.sqlcommand( “delete from Clentes where Cliente=
@ClienteID”, oconnection )

Odeletecommand.parameters.add( new sqlclient.sqlparameter ( “@ClienteID”,
system.data.sqldbtype.int. 5, system.data.parameterdirection.input, true. Ctype(0,byte),
ctype(0,byte), “ClienteID”, system.data.datarowversion.current, nothing ) )

'establece las referencias apropiadas al objeto sobre DataAdapter
With oDataAdapter
.selecctCommand= oSelectCommand
.insertCommand= oInsertCommand
.UpdateCommand= oUpdateCommand
.DeleteCommand= oDeleteCommand
End With
„Cree un espacio para el conjunto de datos vacio
Dim oDataSet as New DataSet()
'Use el Adapter para crear un relleno de la nueva DataTable denominado Clientes
oDataAdapter.Fill ( oDataSet, “Clientes”)
dim snuevonombre as string=”Kevin”
oDataSet.Tables(0).Rows(0).Item(“NombreDeContacto”)= snuevonombre
oDataSet.Update(oDataSet)
oConnection.Close()
Facultad de Estudios Tecnológicos
14



III. REQUERIMIENTOS O MATERIAL Y EQUIPO



Cantidad

Descripción
1 1 PC con Windows y acceso a Internet
2 1 Guía de Laboratorio #10 de LPI
3 1 Memoria USB
IV. PROCEDIMIENTO

Antes de iniciar esta práctica tenga en cuenta lo siguiente:
a) Debe crear una carpeta en Mis Documentos con el nombre de “Práctica10LP1” en la cual va a guardar
todos los archivos del procedimiento y del análisis de resultados.
b) Tome en consideración que la extensión del archivo de la BDD de Access es .mdb solo para Access
2003 o versiones anteriores. En esta práctica utilizará Access 2007 por lo cual será .accdb

Archivo: TazumalSA.accdb

1. Cree una nueva base de datos dentro de su carpeta de trabajo llamada TazumalSA.accdb, la cual
contenga las siguientes tablas y relaciones entre ellas:




















2. Tome en cuenta las restricciones (dominio de valores) de los campos siguientes:

Tabla Dominio de campos de la tabla
Proveedor IdProv: autonumerico y llave primaria
El resto de campos tienen 20 caracteres cada uno, solo el nombre del proveedor y contacto
son obligatorios.
Categoria IdCatego: campo llave primaria de 2 caracteres
El resto de campos son de 30 caracteres cada uno, y exija valor en ellos(no permitir nulos)
Producto IdProd: autonumerico y llave primaria
NomProd: texto de 25 caracteres y no nulo
IdProv: Entero largo y no nulo
IdCatego: texto de 2 caracteres y no nulo
PrecioUnidad: numero Flotante Doble
UnidadesEnExistencia: Entero


JerarquiaEmp IdJerar: autonumerico y llave primaria
NomJerar y FuncionesJerar: texto de 25 y 40 caracteres respectivamente, no nulos.
Empleado IdEmp: autonumerico y llave primaria
Ape1Emp, Ape2Emp, NomsEmp: texto de 10 caracteres no nulos
IdJerar: Numero entero largo no nulo
DirecEmp y TelCasaEmp: texto de 50 y 15 caracteres respectivamente, permitir nulos

3. Ingrese los datos siguientes a cada una de las tablas de la manera apropiada:

JerarquiaEmp
IdJerar NomJerar FuncionesJerar
1 Vicepresidente comercial Dueños del negocio
2 Representante de ventas Interactuar con clientes
3 Gerente de ventas Coordinar representantes de ventas
4 Seguridad Proteger local de ventas

Empleado
IdEmp Ape1Emp Ape2Emp NomsEmp IdJerar DirecEmp TelCasaEmp
1 Castillo Letona Bernando 1 Soyapango 122222
2 Pineda Zelaya Paty 2 El paraiso San Salvador 222888888
3 Giron Moreno Enrique 3 Apopa 556-999
4 Perez A Alicia 3 Soyapango 3244444
5
Garcia Tobar Rosa 3 Ilopango 2545555
6
Garcia Garcia Sergio 4 Las Margaritas
7
Dimas Moreno Juan 4 Mejicanos

Producto
IdProd NomProd IdProv IdCatego PrecioUnidad UnidadesEnExistencia
1 Barrilito 1 a1 1,34 31
2 Pilsener 1 a1 2 100
3 Sardina PICANADA 2 a3 0,67 120

Proveedor
IdProv NombreProv ContactoProv DirecProv Telefono
1 La Constancia Francisco Merino La calle alegre 222-4444
2 La Isla Popeye marino Puerto Libertad 766-3333
3 San Francisco Elizabeth Garcia Santa Tecla 290-1111
4 Pizza Hot Rosa Garcia Colonia Escalon 230-7777

Categoria
IdCatego NomCatego DescripCatego
a1 Bebidas te y cervezas
a2 Lacteos Quesos y Crema
a3 Pescados Sardinas y mariscos
a4 Pastas Mezclas de harina

Facultad de Estudios Tecnológicos 16
Facultad de Estudios Tecnológicos
17


4. Almacene los datos de las tablas y cierre la BDD


APLICACIÓN 1(Formulario1): Obtener registros de SELECT de una tabla o
sino de tablas relacionadas

5. Incluya en su proyecto a un archivo de Modulo de variables y digite en el las líneas siguientes:

Dim sAppPath As String = Application.StartupPath.ToString
Dim sBaseDatos As String = sAppPath & "\TazumalSA.accdb"
Public CadConex As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" &
sBaseDatos '& ";Persist Security Info=False"

6. Diseñe el form siguiente y luego ajuste las propiedades de los controles descritos en la tabla










DataGridView1














Cuadro de propiedades
Control Propiedad Valor
Control Propiedad Valor
Form1 Name Formulario1 DataGridView1 Name Grid1
Button1 Text Ver Resultados RadioButton1 Text SELECT
GroupBox1 Text Selección de
Consulta SQL
RadioButton2 Text INNER
JOIN
RadioButton3 Text LEFT JOIN

7. Digite los códigos siguientes de acuerdo a la ubicación indicada

 A nivel del modulo de clase (antes de la declaración de clase), importe el espacio de nombres del
proveedor OLEDB a utilizar: Imports System.Data.OleDb

 Dentro del modulo de la clase Formulario1
'Demostracion de diferentes consultas SELECT SQL
Dim CadSQL As String 'texto del comando SQL
Facultad de Estudios Tecnológicos
18
'Usa objetos de clases de proveedor OLEDB
Dim Conex As OleDbConnection
Dim DAempleado As OleDbDataAdapter
 En la subrutina de evento Load del Formulario1

'Define conexion a una BDD de Access
Conex = New OleDbConnection(CadConex)
Conex.Open() 'Activa la conexion
'Diferentes tipos de consultas Select entre una o 2 tablas(relacionadas)
'Primera opcion
CadSQL = "select NomProd,PrecioUnidad,(PrecioUnidad*8.75) as Colones,
UnidadesEnExistencia as Existencia from Producto"


 En cada subrutina de evento CheckedChanged de cada radiobutton escriba una de estas líneas:
Radiobutton1:
CadSQL = "select NomProd,PrecioUnidad,(PrecioUnidad*8.75) as
Colones,UnidadesEnExistencia as Existencia from Producto"

Radiobutton2:
CadSQL = "select a.IdProv,a.NombreProv,b.NomProd from Proveedor a inner join
Producto b on a.IdProv=b.IdProv"

Radiobutton3:
CadSQL = "select a.IdProv,a.NombreProv,b.NomProd from Proveedor a left join
Producto b on a.IdProv=b.IdProv"

 En subrutina de evento Clic de Button1
'Muestra resultados de consulta seleccionada
Dim c, f, H As Integer 'Contadores de columnas, filas y usosVarios

'Objeto DataSet: define y se instancia "vacio" (sin datos)
Dim DSemp As New DataSet

'Crea un DataAdapter que copie registros segun la consulta SQL
DAempleado = New OleDbDataAdapter(CadSQL, Conex)
'Extrae registros en el 1er DataTable del DataSet(DSemp)
DAempleado.Fill(DSemp, "ListaProductos")

'Enlaza Grid a los registros dentro del DataSet
Grid1.DataSource = DSemp
Grid1.DataMember = "ListaProductos"

'Dos formas de referenciar a los datos dentro de un mismo DataTable
c = DSemp.Tables("ListaProductos").Columns.Count 'Total de campos(columnas) de
consulta
f = DSemp.Tables(0).Rows.Count 'Total de filas de consulta SQL

'Muestra calculos obtenidos desde el DataSet
With ListBox1.Items
.Clear()
.Add(" RESULTADOS:")
.Add("Total de Campos: " + c.ToString)
.Add(" Lista Campos >>")
For H = 0 To c - 1
.Add(Str(H + 1) + ". " + DSemp.Tables(0).Columns(H).Caption)
Facultad de Estudios Tecnológicos
19
Next
.Add(" ")
.Add("Total de Reg: " + f.ToString)
End With

'Libera memoria de objetos OLEDB utilizados
DSemp = Nothing
DAempleado = Nothing

8. Incluya un botón extra al form y en su evento Clic usted programe una línea con la cual cerrara la
conexión hacia la BDD del objeto Conex.
9. Guarde su proyecto y ejecute la aplicación
10. Analice con mucho cuidado las diferencias entre las 3 consultas SQL SELECT y responda las
preguntas siguientes:

a) De la primera consulta, ¿Por qué no da un error el campo llamado Colones (ya que no existe un
campo llamado Colones en ninguna de las tablas)?. ¿Por qué lo permite el SQL?
b) En la segunda y tercer consulta, ¿Cómo se denominan a las letras a y b que acompañan a los
campos y los nombres de las tablas?
c) ¿Cuáles son las diferencias entre los resultados de la 2da y 3er consulta?, Explique


APLICACIÓN 2 (FormDataReader): u tilizar u n en tor n o “ Cone ctado
a la
B DD” para lee r registros de tabl as

11. Incluya un nuevo Form dentro del proyecto. Llámele FormDataReader. Luego elabore el siguiente
diseño de controles:




12. Cambie la propiedad Text de controles Button1 a Button3 por: Crear Conexión, Llenar DataReader,
Leer Registros, respectivamente.
13. Digite los segmentos de código en los bloque indicados:

 Importe el espacio de nombres System.Data.OleDb: Imports System.Data.OleDb

 A nivel local dentro de la clase del form FormDataReader:
Facultad de Estudios Tecnológicos
20

'Demostracion de uso de metodos/funciones del DataReader
Dim TextSql As String 'consulta SQL Select
Dim conexOle As OleDbConnection
Dim cmdSelect As OleDbCommand
Dim drEmpleado As OleDbDataReader

 En la subrutina de evento Load del form
Button1.Enabled = True
Button2.Enabled = False
Button3.Enabled = False

 En subrutina de evento Clic del Button1
'Definiendo conexion actual y activandola
Try
conexOle = New OleDbConnection(CadConex) 'Crea una nueva conexion
conexOle.Open() 'Intenta active la conexion
If conexOle.State = ConnectionState.Open Then
MsgBox("Conexion creada correctamente y abierta")
End If

'Creando un objeto Command "vacio"
cmdSelect = New OleDbCommand

'Ajustando botones activos
Button1.Enabled = False
Button2.Enabled = True
Button2.Focus()

Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.OkOnly, "Error al crear Conexion")
End Try

 En evento Clic del Button2

Try
'Escriba consulta SELECT para tabla Empleado
TextSql = "select * from Empleado"
'configurando command con instruc SQL dicha por usuario
With cmdSelect
.CommandText = TextSql
.CommandType = CommandType.Text
.Connection = conexOle
End With
'Ejecuta la instrucción del command y devuelve un objeto DaraReader
drEmpleado = cmdSelect.ExecuteReader
MsgBox("DataReader listo para ser leido")
Button2.Enabled = False
Button3.Enabled = True

Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.OkOnly, "Error")
End Try
Facultad de Estudios Tecnológicos
21
 En subrutina de evento Clic del Button3

'Demostrando los metodos de recuperacion de valores del DataReader
'De la consulta SQL ejecutada: Total de..
Dim TC As Integer '.. Campos
Dim TF As Integer '.. Registros
Dim q As Integer 'Contador usos varios
Dim Valores As String 'secuencia valores-Campos de c/fila
TF = 0 'inicio (ningun registro)

With drEmpleado
TC = .FieldCount
ListBox1.Items.Add("Total de Campos de Select: " + Str(TC))
ListBox1.Items.Add("NOMBRES DE CAMPOS:")
For q = 0 To TC - 1
ListBox1.Items.Add("(" + Str(q + 1) + ") " + .GetName(q))
Next q

'Mostrando el nombre completo de empleado de c/fila almacenado
ListBox2.Items.Add("LISTA DE EMPLEADOS:")
While drEmpleado.Read()
TF = TF + 1 'actualiza conteo registro

'Metodo 1: Usando funcion GetString(Id campo)
'Valores = .GetString(1) + " " + .GetString(2) + " , " + .GetString(3)
'ListBox2.Items.Add(Valores)

'Metodo 2: Usando metodo Item( ) gracias a sobrecarga de metodo
Valores = .Item("NomsEmp") + " " + .Item("Ape1Emp") + " " +
.Item("Ape2Emp")

Valores = .Item(3) + " " + .Item(1) + " " + .Item(2)
ListBox2.Items.Add(Valores)
End While
ListBox2.Items.Add("Total Reg= " + Str(TF))
End With

14. Modifique las propiedades del proyecto para que comience desde el objeto FormDataReader y
guarde el proyecto.

15. Ejecute el programa y presione el botón activado para ver la secuencia de pasos de como se activa la
conexión, como se crea un Command y como un DataReader permite leer los registros que cumplen
el comando SQL Select escrito en la propiedad .CommandText de un Command.

16. Incluya un msgbox(mostrando valor de variable TF) dentro del While que lee cada registro
proporcionado por el DataReader. Guarde los cambios y ejecute de nuevo el programa.

17. Usted verá que los registros se van leyendo de uno en uno, en secuencia en una sola dirección.


APLICACIÓN 3 (MantenimientoTablas): Como dar mantenimiento a
registros de una o dos tablas(relacionadas)

18. Diseñe el siguiente formulario:
Facultad de Estudios Tecnológicos
22

DataGridView1































DataGridView2


19. A continuación se presentan las propiedades a modificar:

OBJETO PROPIEDAD VALOR
DataGrid1 y DataGrid2 Name Grid1 y Grid2 respectivamente
Button1 Text CargaDatos y Enlace
Button2 Text Definir Relación
Button3 Text Definir CommandSQL
Button4 Text Actualizar Tablas


20. Digite los codigos siguientes de acuerdo al segmento de bloque indicado
 Importe el espacios de nombres: Imports System.Data.OleDb

 A nivel de la clase del Form

Dim CadSQL As String 'texto del comando SQL
Dim i As Integer 'Contador para estructuras repetitivas
Dim Cone As OleDbConnection
Dim DAjerar, DAemp As OleDbDataAdapter
Dim DScomun As New DataSet

 En el evento Load del form

'Carga de datos desde 2 tablas relacionadas (uno a varios), y la definicion de
esta relacion
Facultad de Estudios Tecnológicos
23
'Para demostrar que si se borra un reg de tabla primaria, se borraran en
cascada
'reg relacionados en tabla derivada
'Crea una nueva conexion a la BDD de Access
Cone = New OleDbConnection(CadConex)
Cone.Open() 'Activa la conexion

 En evento Clic del Button1

Try
'Usa la conexion actual(Cone) para cargar datos de 2 DataAdapter diferentes
'pero los registros resultantes se cargaran DENTRO DE UN UNICO
DataSet(DScomun).
'Este DataSet colocara cada retorno de registros en objetos DataTable
diferentes
'Cargando datos de tabla1(Tabla principal de la relacion): JerarquiaEmp
CadSQL = "select * from JerarquiaEmp"
DAjerar = New OleDbDataAdapter(CadSQL, Cone)
'Extrae Esquema/definiciones de las columnas de tabla "JerarquiaEmp"
DAjerar.FillSchema(DScomun, SchemaType.Source, "JerarquiaEmp")
'Extrae reg hacia DataTable dentro del DScomun
DAjerar.Fill(DScomun, "JerarquiaEmp")

'Cargando datos de tabla2(Tabla secundaria de la relacion): Empleado
CadSQL = "select * from Empleado"
DAemp = New OleDbDataAdapter(CadSQL, Cone)

'Extrae Esquema/definiciones de las columnas de tabla "Empleado"
DAemp.FillSchema(DScomun, SchemaType.Source, "Empleado")
'Extrae reg hacia DataTable dentro del DScomun
DAemp.Fill(DScomun, "Empleado")

'Cargo los resultados en grid enlazados a cada DataTable dentro
'de un mismo DataSet comun
Grid1.DataSource = DScomun
Grid1.DataMember = "JerarquiaEmp"

Grid2.DataSource = DScomun
Grid2.DataMember = "Empleado"

Grid2.Columns(0).ReadOnly = True
'Grid2.Columns(0).Visible = False

'Enlazo un control ListBox con un campo de primera tabla
With ListBox1
.DataSource = DScomun.Tables("JerarquiaEmp")
.DisplayMember = "NomJerar" 'Campo que muestra
.ValueMember = "IdJerar" 'Campo enlace del valor mostrado
End With

MsgBox("Total de tablas cargadas: " + DScomun.Tables.Count.ToString)
Button1.Enabled = False
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.OkOnly, "OCURRIO EXCEPCION")
End Try
Facultad de Estudios Tecnológicos
24


 En evento Clic del Button2

'Prepara pasos para definir relación entre tablas desde el DataSet que los
tiene almacenado

'PARA COMENZAR:
'declaro Objetos de clases (DataColumn y ForeignKeyConstraint) para establecer
'relacion(primaria - secundaria) entre las 2 tablas: JerarquiaEmp y Empleado
Dim dcT1, dcT2 As DataColumn 'Definic Pura de CampoTabla en ambas tablas

'definicion completa de todos los campos(primarios y secundarios) de c/tabla
Dim dcJerar(2), dcEmp(2) As DataColumn
Dim FKJerarEmp As ForeignKeyConstraint

'1: extraido definicion del campo IdJerar de ambas DataTable porque
'es el campo que permite relacion (uno a varios)
dcT1 = DScomun.Tables("JerarquiaEmp").Columns("IdJerar")
dcT2 = DScomun.Tables("Empleado").Columns("IdJerar")

'Defino conjunto de campos (DataColumn) que hacen la
'llave(primaria) en c/tabla relacionada
dcJerar(0) = dcT1
dcEmp(0) = DScomun.Tables("Empleado").Columns("IdEmp")
dcEmp(1) = dcT2

'2: Defino en objetos DataTable del DataSet Comun quienes son sus
'campos llaves(con sus caracteristicas, en especial si es autonumico)
DScomun.Tables("JerarquiaEmp").PrimaryKey = dcJerar
With DScomun.Tables("Empleado")
.PrimaryKey = dcEmp
'Indica que campo llave(IdEmp) es de solo lectura y autonumerico
'.Columns("IdEmp").AutoIncrement = True
'.Columns("IdEmp").ReadOnly = True
'MsgBox("AutoIncrementSeed= " +
.Columns("IdEmp").AutoIncrementSeed.ToString)
End With

'3: "explica" la relacion Uno-Varios definiendo un objeto ForeignKeyConstraint
FKJerarEmp = New ForeignKeyConstraint(dcT1, dcT2)
FKJerarEmp.UpdateRule = Rule.Cascade 'Que actualice en cascada reg
relacionados
FKJerarEmp.DeleteRule = Rule.Cascade 'Que borre en cascada reg relacionados

'4: agrega la relacion anterior al DataSet comun
DScomun.Tables("Empleado").Constraints.Add(FKJerarEmp)

Button2.Enabled = False


 En el Button3 en su evento Clic

'Preparo los 3 command minimos que necesita la conexion para actualizar
registros.
'Estos command son las 3 instrucciones SQL: Update, Insert y Delete
Facultad de Estudios Tecnológicos
25
'Fijese MUY BIEN CADA LINEA, LA SECUENCIA GENERAL Y LOS COMENTARIOS
RESPECTIVOS

Try
'Defino comando SQL para que actualice(update) registros en tabla "Empleado"
Dim cmdActuali As New OleDbCommand("update Empleado set
Ape1Emp=?,Ape2Emp=?,NomsEmp=?,DirecEmp=?,TelCasaEmp=? where IdEmp=? and
IdJerar=?")

'Le Agrego parametros que necesita instrucc SQL UPDATE anterior
cmdActuali.Parameters.Add(New OleDbParameter("@Ape1Emp",
OleDb.OleDbType.Char, 10, "Ape1Emp"))
cmdActuali.Parameters.Add(New OleDbParameter("@Ape2Emp",
OleDb.OleDbType.Char, 10, "Ape2Emp"))
cmdActuali.Parameters.Add(New OleDbParameter("@NomsEmp",
OleDb.OleDbType.Char, 10, "NomsEmp"))
cmdActuali.Parameters.Add(New OleDbParameter("@DirecEmp",
OleDb.OleDbType.Char, 50, "DirecEmp"))
cmdActuali.Parameters.Add(New OleDbParameter("@TelCasaEmp",
OleDb.OleDbType.Char, 15, "TelCasaEmp"))
cmdActuali.Parameters.Add(New OleDbParameter("@IdEmp",
OleDb.OleDbType.BigInt, 2, "IdEmp"))
cmdActuali.Parameters.Add(New OleDbParameter("@IdJerar",
OleDb.OleDbType.Integer, 2, "IdJerar"))
cmdActuali.Connection = Cone 'Conexion abierta a la cual esta enlazado
DataAdapter que este comando

'Defino comando SQL para que agregue(insert) nuevos registros en tabla
"Empleado"
'Dim cmdActuali As New OleDbCommand("update Empleado set Ape2Emp=? where
IdEmp=? and IdJerar=?")
Dim cmdNuevo As New OleDbCommand("insert into
Empleado(Ape1Emp,Ape2Emp,NomsEmp,IdJerar, DirecEmp,TelCasaEmp) values
(?,?,?,?,?,?)")

'Le Agrego parametros que necesita instrucc SQL UPDATE anterior
With cmdNuevo.Parameters
.Add(New OleDbParameter("@Ape1Emp", OleDb.OleDbType.Char, 10,
"Ape1Emp"))
.Add(New OleDbParameter("@Ape2Emp", OleDb.OleDbType.Char, 10,
"Ape2Emp"))
.Add(New OleDbParameter("@NomsEmp", OleDb.OleDbType.Char, 10,
"NomsEmp"))
.Add(New OleDbParameter("@IdJerar", OleDb.OleDbType.Integer, 2,
"IdJerar"))
.Add(New OleDbParameter("@DirecEmp", OleDb.OleDbType.Char, 50,
"DirecEmp"))
.Add(New OleDbParameter("@TelCasaEmp", OleDb.OleDbType.Char, 15,
"TelCasaEmp"))
End With
cmdNuevo.Connection = Cone 'Conexion abierta a la cual esta enlazado
DataAdapter que este comando

'Defino comando SQL para que borre registros en tabla "Empleado"
Dim cmdBorrar As New OleDbCommand("delete from Empleado where IdEmp=?")
cmdBorrar.Parameters.Add(New OleDbParameter("@IdEmp",
OleDb.OleDbType.Integer, 2, "IdEmp"))
Facultad de Estudios Tecnológicos
26
cmdBorrar.Connection = Cone 'Conexion abierta a la cual esta enlazado
DataAdapter que este comando

'Asigno Command configurados al DataAdapter
DAemp.DeleteCommand = cmdBorrar
DAemp.UpdateCommand = cmdActuali
DAemp.InsertCommand = cmdNuevo

Button3.Enabled = False

Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.OkOnly, "OCURRIO EXCEPCION")
End Try

 Del Button4 y su evento Clic

'Actualizacion de reg modificados en tabla (Empleados: Tabla secundaria de la
relacion)
'hacia la BDD.

'Procede a realizar la actualizac(Nuevo,Modificac y Borrado) de registros de
Empleados solamente
DAemp.Update(DScomun, "Empleado") Cone.Close()
'Cierro la conexion actual
MsgBox("Actualizaciones de la BDD finalizadas")

21. Guarde los cambios del proyecto.
22. Ahora ejecute el proyecto y de clic solamente en el 1er botón (cargar de datos y enlace). Verá que se
muestran los registros de 2 tablas de la BDD (JerarquiaEmp y Empleado, las cuales según la BDD
están relacionadas). Además observe que en el ListBox1 se muestran los mismos registros de la 1er
tabla (JerarquiaEmp). Lo anterior porque la propiedad DataSource y DataMember de cada control se
enlazan al 1er DataTable del DataSet DSComun.

23. Ahora modifique en el Grid2 algunos de los datos de empleados como apellidos, nombre, etc.
Incluso busque la ultima fila e incluya datos de nuevos empleados (teniendo cuidado de cumplir la
integridad referencial de los campos llaves foráneas). Finalice la aplicación y luego busque el archivo
de la BDD.

Observe el contenido de los empleados que modificó en la aplicación y vera que no hizo ningún cambio.
¿Por qué? porque ADO.NET funciona de una manera desconectada y solo se conecta a la BDD para hacer
una copia de registros, ejecutar funciones, actualizar apropiadamente los registro de tablas y otros, para
luego desconectarse.

24. Ejecute de nuevo la aplicación y repita el paso anterior. De clic en el Button4 después modificar los
datos en el Grid2. Verá que NET activa una excepcion (un error) para avisar que no se han
establecidos los parámetros de los Command que posee el DataSet para saber como realizar las
actualizaciones SQL (Insert, Update y Delete).
Sin estos command dentro de un DataSet, este no sabe como relacionar los datos de registros
(almacenados en sus DataTable y los cuales se han podido modificar o eliminar) con los registros
“reales” de las tablas en la BDD

25. De nuevo vuelva a ejecutar el programa, pero esta vez realice los pasos según este algoritmo:

a) Clic en el 1er botón para así enlazarse a la BDD y cargar los datos de las 2 tablas, para mostrarlos
en los Grid‟s.
Facultad de Estudios Tecnológicos
27
b) Clic en el segundo y tercer botón en ese orden
c) Ubíquese en el Grid2, recorra a los registros de empleados y fíjese el cargo que tiene cada uno.
d) Modifique datos de empleados existentes. Además vaya a fila del último empleado y observe que
al querer incluir un nuevo empleado, el campo auto numérico sigue el próximo número de la
secuencia. Cuide los valores de campos llaves para así mantener la integridad referencial. Por
ultimo, apunte el IdEmp de algunos empleados antes de que los borre.
e) Finalizadas las modificaciones, toque el Button4.

26. Gracias al código ejecutado por Button2 y Button3 se establecen en el DataSet (DScomun) las
relaciones entre las tablas (JerarquiEmp y Empleado) y restricciones de sus campos. Y en especial se
definen los Command con las instrucciones SQL (Insert, Update y Delete) que le permitirá
coordinarse con la BDD para modificar apropiadamente los registros de sus tablas.

27. Como ya se ha dado cuenta, cuando usted modifica, elimina o agrega registros en el Grid2 y luego
da clic en Button4, los cambios son realizados en la base de datos siempre y cuando siga los pasos del
punto 25. Esto mismo no ocurre si usted modifica, elimina o agrega registros en el Grid1. Realice las
modificaciones necesarias para efectuar estas 3 operaciones en la tabla JerarquiaEmp.



V. ANALISIS DE RESULTADOS

MiniProyecto: Crear un programa para dar mantenimiento a una bases de datos, de
la empresa “El Buen Pastor” la cual es una distribuidora a nivel de Latinoamérica
de artículos de todo tipo para iglesias. El programa debe ser capaz de mostrar las
ventas totales del día, los envíos realizados a cada país y la cantidad de productos
También debe permitir que el administrador ingrese pedidos, tiendas clientes y
todos los datos de esta, nuevos artículo, precio, etc. Tome en cuenta que la
distribuidora posee dos bodegas diferentes y no hace envíos de menos de 500
dólares, a menos que se cobre un recargo. El programa también debe trabajar con
una cantidad de autos disponibles para los envíos, teniendo en cuenta que habrán
envíos grandes (Furgones), Medianos (Camionetas) y pequeños (autos pequeños).
Se tomara en cuenta el diseño de la base de datos, para esta tarea formar grupos según la
cantidad indicada por su docente.