Professional Documents
Culture Documents
etc. que aparecen en este libro son marcas registradas de sus respectivas
compaiiias u organizaciones.
Introduccion
.. ....................................................................................................... 18
Soluciones de acceso a datos .............................................................................................. 20
ADONET ................................................................................................................................ 20
Visual Studio .NET ............................................................................................................... 21
Objetivos de este libro ......................................................................................................... 21
Estructura del libro ............................................................................................................... 22
Ayuda a1 lector ...................................................................................................................... 24
.
Parte I Sentar las bases................................................................................... 25
.
2 SQL y sus dialectos ....................................................................................... 44
iQu6 es SQL?.......................................................................................................................... 46
Partes de SQL ................................................................................................................... 46
Derivados de SQL ........................................................................................................... 47
Ejecuci6n de sentencias SQL ........................................................................................ 47
DDL .......................................................................................................................................... 48
Creaci6n de una base de datos ..................................................................................... 51
Creaci6n de tablas ........................................................................................................... 51
Modificaci6n y borrado de tablas ............................................................................... 54
Otras operaciones de definici6n de datos ................................................................. 54
DML .......................................................................................................................................... 56
Inserci6n de datos ........................................................................................................... 57
Recuperaci6n de datos ................................................................................................... 58
Alias de tablas ............................................................................................................ 58
Selecci6n de filas ........................................................................................................ 59
Condicionales complejos .......................................................................................... 59
Orden de las filas ....................................................................................................... 61
Expresiones y funciones de resumen .................................................................... 61
Agrupamiento ............................................................................................................. 62
Enlaces entre tablas ................................................................................................... 62
Consultas dentro de consultas ............................................................................... 63
Actualizacibn de datos ................................................................................................... 64
Eliminaci6n de datos ...................................................................................................... 65
DCL ........................................................................................................................................... 65
Derivados de SQL ................................................................................................................. 66
Transact-SQL .................................................................................................................... 66
Variables y tipos de datos ....................................................................................... 67
Evaluaci6n de expresiones ...................................................................................... 68
Condicionales y bucles ............................................................................................. 68
Codificaci6n de procedimientos almacenados ................................................... 69
PL / SQL .............................................................................................................................. 69
Programacidn de bases de datos con Visual Basic .NET
.
3 Origenes de datos .......................................................................................... 74
Origenes locales y remotos ................................................................................................. 75
Microsoft Access ................................................................................................................... 76
Definicion de las tablas .................................................................................................. 77
Relaci6n entre las tablas ................................................................................................ 79
Introducci6n de datos .................................................................................................... 79
Simplificar la selecci6n de editorial ............................................................................ 81
SQL Server .............................................................................................................................. 83
Creaci6n de la base de datos ........................................................................................ 84
Definici6n de las tablas .................................................................................................. 85
Relacidn entre las tablas ................................................................................................ 87
Introducci6n de datos .................................................................................................... 89
Us0 de la base de datos de ejemplo ............................................................................ 90
Definici6n de una vista .................................................................................................. 91
Definir procedimientos almacenados ......................................................................... 93
Ejecuci6n de procedimientos almacenados .............................................................. 95
Oracle ....................................................................................................................................... 96
Creaci6n de la base de datos ........................................................................................ 97
Definicion de las tablas .................................................................................................. 98
Introducci6n de datos .................................................................................................. 104
Definici6n de una vista ................................................................................................ 105
Definir funciones y procedimientos almacenados ................................................ 106
Ejecuci6n de funciones y procedimientos ............................................................... 110
InterBase ................................................................................................................................ 111
Creaci6n de la base de datos ...................................................................................... 113
Definicidn de las tablas ................................................................................................ 115
Introduccidn de datos .................................................................................................. 116
Definici6n de una vista ................................................................................................ 117
Definir procedimientos almacenados ....................................................................... 118
Ejecuci6n de procedimientos almacenados ............................................................ 120
Microsoft Excel .................................................................................................................... 120
Creaci6n de un nuevo libro ........................................................................................ 121
Definici6n de la estructura .......................................................................................... 121
Introducci6n de datos .................................................................................................. 123
XML ........................................................................................................................................ 125
Definici6n de la estructura de documento .............................................................. 125
Creaci6n del documento XML ................................................................................... 128
Directorio activo .................................................................................................................. 133
Acceso a1 Directorio activo ......................................................................................... 133
Resumen ................................................................................................................................ 134
.
5 Modelo de objetos ....................................................................................... 152
Estructura del modelo de objetos ................................................................................... 153
Ambitos con nombre de ADO.NET ................................................................................ 154
Interfaces para 10s proveedores ...................................................................................... 155
Asociaci6n de columnas y tablas ............................................................................... 156
Acceso a filas de datos ................................................................................................. 156
Adaptadores de datos .................................................................................................. 159
Conexiones, comandos y transacciones ................................................................... 160
Detalles sobre 10s proveedores ........................................................................................ 161
Otras clases comunes y especificas ........................................................................... 162
Clases independientes del origen de datos .................................................................. 163
Conjuntos de datos ....................................................................................................... 164
Tablas ................................................................................................................................ 165
Filas ................................................................................................................................... 166
Columnas ......................................................................................................................... 167
Restricciones ................................................................................................................... 168
Relaciones ........................................................................................................................ 168
Vistas de datos ............................................................................................................... 169
Resumen ................................................................................................................................ 170
. . . al origen de datos
6 Conexion ........................................................................ 172
Obtencion e instalaci6n de proveedores adicionales ................................................. 173
D6nde obtener 10s proveedores ................................................................................. 174
Instalaci6n del proveedor ............................................................................................ 174
Generalidades sobre la conexi6n ..................................................................................... 176
Cadena de conexi6n ...................................................................................................... 176
Apertura y cierre de la conexi6n ............................................................................... 177
Propiedades informativas ........................................................................................... 178
Cadenas de conexi6n .......................................................................................................... 178
Programacidn de bases de datos con V i s u a l Basic .N.ET
.
7 Informacibn de esquema de la base de datos .......................................... 200
iQu6 es la informaci6n de esquema? ............................................................................. 201
Origenes OLE DB ................................................................................................................ 202
Tabla de resultados ....................................................................................................... 203
En la practica .................................................................................................................. 204
Otros origenes ...................................................................................................................... 206
En la practica .................................................................................................................. 206
Informaci6n sobre columnas ............................................................................................ 209
En la practica .................................................................................................................. 210
Resumen ................................................................................................................................ 212
. . . de datos
8 Recuperacion ................................................................................ 214
Generalidades sobre 10s comandos ................................................................................ 215
Asociaci6n entre comando y conexi6n ..................................................................... 216
Definicion del comando a ejecutar ............................................................................ 217
Ejecuci6n del comando ................................................................................................ 217
Lectura de 10s datos ........................................................................................................... 219
Recuperar el contenido de una tabla ........................................................................ 220
Varios conjuntos de datos ........................................................................................... 222
Ejecuci6n de sentencias de selecci6n ........................................................................ 223
Sentencias con parhmetros .......................................................................................... 226
Recuperaci6n de un solo valor ................................................................................... 228
Manipulacidn de datos ...................................................................................................... 228
Otras operaciones ................................................................................................................ 229
Recuperaci6n de una vista ......................................................................................... 230
fndice de contenidos
.
10 Relaciones y vistas ..................................................................................... 270
Filtrado y ordenaci6n de un DataTable ......................................................................... 272
Generalidades sobre DataView y DataViewManager ............................................... 274
Funcionamiento de un DataView .............................................................................. 276
Funcionamiento de un DataViewManager ............................................................. 277
En la pr6ctica ........................................................................................................................ 278
Multiples vistas sobre una misma tabla .................................................................. 278
La vista por defect0 de una tabla .............................................................................. 279
Busqueda de datos en una vista ................................................................................ 281
Edici6n de datos en la vista ........................................................................................ 284
Us0 de un DataViewManager .................................................................................... 286
Resumen ................................................................................................................................ 289
.
14 Componentes con vinculacih a datos ................................................... 368
Tipos de vinculaci6n .......................................................................................................... 369
Vinculaci6n simple ........................................................................................................ 370
Vinculaci6n con mtiltiples filas de una columna ................................................... 374
Vinculaci6n con mtiltiples filas y columnas ........................................................... 376
Enlace a datos en formularios Windows ...................................................................... 377
Posici6n actual en una lista de datos ........................................................................ 378
Control de la vinculaci6n ............................................................................................ 379
Componentes enlazables ............................................................................................. 379
Enlace a datos en formularios Web ................................................................................ 380
Vinculos s610 de lectura ............................................................................................... 380
Navegaci6n con componentes simples .................................................................... 381
Actualizaci6n del origen .............................................................................................. 385
Resumen ................................................................................................................................ 386
.
15 Formularios de datos ................................................................................ 388
El asistente para formularios Windows ........................................................................ 389
Selecci6n del DataSet .................................................................................................... 390
Definici6n de la conexi6n ............................................................................................ 391
Selecci6n de 10s elementos de origen ....................................................................... 391
Definir la relacion entre las tablas ............................................................................ 392
Selecci6n de columnas .................................................................................................. 393
Elegir el diseiio del formulario .................................................................................. 395
Personalizaci6n del diseiio .......................................................................................... 396
Antilisis del c6digo generado ..................................................................................... 397
El asistente para formularios Web .................................................................................. 401
Antilisis del c6digo generado ..................................................................................... 402
Aiiadir capacidades de edici6n .................................................................................. 404
Inserci6n de 10s enlaces de edici6n ..................................................................... 404
Eventos y elementos de un DataGrid ................................................................. 405
C6digo asociado a 10s eventos ............................................................................. 406
Actualizaci6n del origen de datos ....................................................................... 408
Resumen ................................................................................................................................ 410
Prograrnacidn de bases de datos con Visual Basic .NET
.
20 Tablas con columnas calculadas ............................................................. 450
Columnas calculadas en la sentencia SQL .................................................................... 451
Afiadir columnas a un DataTable ................................................................................... 453
Creacih de un nuevo Datacolumn ......................................................................... 453
Creaci6n en fase de disefio .......................................................................................... 454
.
21 Almacenamiento y recuperaci6n de imagenes ...................................... 458
Afiadir una columna para la portada ............................................................................ 459
Columnas binarias .............................................................................................................. 460
Disefio del formulario Windows ..................................................................................... 462
Recuperar la imagen de la base de datos ................................................................ 464
Asignar una imagen desde un archivo .................................................................... 465
fndice de contenidos
.
22 Creaci6n de proveedores ADO.NET ...................................................... 468
Inicio del proyecto .............................................................................................................. 470
FileSystemClientConnection ............................................................................................ 471
FileSystemClientCommand .............................................................................................. 474
FileSystemClientDataReader ............................................................................................ 479
FileSystemClientDataAdapter ......................................................................................... 485
Prueba del proveedor ......................................................................................................... 487
Ejecuci6n de un comando ............................................................................................ 488
Us0 del lector de datos ................................................................................................ 488
Us0 del adaptador de datos ........................................................................................ 489
........................................................................................................
A . Glosario 500
B. Contenido del CD-ROM ............................................................................ 506
Us0 de 10s ejemplos ............................................................................................................ 507
Atencion a1 lector ................................................................................................................ 509
Aunque es posible utilizar todos 10s servicios de ADO.NET sin m6s ayuda que
un editor de textos simple y el compilador de Visual Basic .NET, ejecutable desde
la linea de comandos, el entorno de Visual Studio .NET puede, en ocasiones, faci-
litar de forma notable nuestro trabajo. Dicho entorno cuenta con elementos que,
como el Explorador de servidores, nos permiten establecer conexiones con orige-
nes de datos, seleccionar conjuntos de informacibn, definirlos, crear autom6tica-
mente 10s objetos necesarios para acceder a ellos desde programa, etc.
Independientemente de que est4 utilizando VisuaZ Basic . N E T Standard o alguna
de las ediciones de Visual Studio .NET, Professional, Enterprise Developer o Enterprise
Architect, hay ciertas operaciones b6sicas que siempre tendremos a1 alcance. Otras,
por el contrario, s610 est6n disponibles en las ediciones superiores.
Una vez que nos hayamos familiarizado con ADO.NET, y sepamos c6mo usar
sus clases para efectuar todas las operaciones habituales, veremos cdmo aprove-
char las posibilidades del entorno de Visual Studio .NET.
El libro que tiene en sus manos no est6 pensado para aprender a programar con
Visual Basic .NET, familiarizarse con el entorno de Visual Studio .NET o bien co-
nocer 10s servicios bdsicos de la plataforma .NET para la creaci6n de aplicaciones
Windows, aplicaciones y servicios Web. Todos esos conocimientos se asume que el
lector ya 10s tiene, lo cual nos permite centrarnos especificamente en un tema: el
acceso a datos con ADO.NET desde Visual Basic .NET. No es &te, por tanto, un
In troduccidn
libro adecuado para aquellos que desconocen el lenguaje o el entorno, a 10s cuales
recomendamos titulos como Programacidn con Visual Basic .NET o Guia pra'ctica para
usuarios de Visual Studio .NET, de la misma editorial y de tip0 mas gen6rico.
A diferencia de otros titulos, en 6ste no se parte de que el lector conoce ADO, el
mecanismo de acceso a datos empleado en Visual Basic 6.0 y otras herramientas
previas a la aparici6n de Visual Studio .NET, ni DAO ni ninguna otra soluci6n pre-
via. No encontrari, por tanto, comparativas entre 10s objetos de ADO y ADO.NET
o descripcih de procesos tomando como base 10s de ADO. Con este libro podra
usar ADO.NET sin necesidad de conocer previamente ningh-i otro mecanismo de
acceso a datos, tan s610 necesita saber c6mo utilizar Visual Basic .NET para cons-
truir aplicaciones Windows y Web.
Para alcanzar estos objetivos es indispensable que su configuraci6n, la del equi-
PO donde va a probar 10s ejemplos propuestos, cuente con estos elementos:
0 Tener instalado Visual Basic .NET Standard o algunas de las ediciones de Vi-
sual Studio .NET. El autor ha empleado la edici6n Enterprise Architect de Vi-
sual Studio .NET, si bien la mayor parte del contenido es aplicable a cualquier
edicih, incluida la citada Visual Basic .NET Standard.
Contar con una unidad de CD-ROM desde la cual recuperar 10s ejemplos del
disco que acompaiia a1 libro, copiindolos en su sistema.
0 Disponer del software cliente y servidor de datos usado en 10s ejemplos, en-
tre otros Microsoft Access, Microsoft SQL Server 7/2000, Oracle 8i e InterBase.
En 10s capitulos respectivos se tratarin las bases de estas aplicaciones y, en
algunos casos, se indicara c6mo obtenerlas, instalarlas y configurarlas en su
sistema.
A1 redactar este libro se ha tenido como primer punto de mira el contenido di-
dictico, por ello 10s fundamentos y conocimientos se van abordando de manera
escalonada, capitulo a capitulo, asumiendo que 6sa sera la secuencia inicial de lec-
tura. No obstante, muchos capitulos tambien pueden usarse a mod0 de consulta o
referencia, una vez que haya adquirido la visi6n global de 10s temas que se tratan.
El libro esti dividido en cuatro partes: Sentar las bases, ADO.NET, Visual Studio
.NET y Resolucidn de cusos concretos. La primera de ellas, compuesta de tres capitu-
los, nos servirii para conocer la terminologia que va a utilizarse a lo largo del libro,
asi como unos fundamentos del lenguaje SQL y ciertas aplicaciones que pueden
actuar como origenes de datos.
La segunda parte se centra en el estudio de ADO.NET, sus clases y la forma de
usarlas para conectar con un origen de datos, recuperar informacih, manipularla
y devolverla. Aprender6 a acceder a distintos origenes de datos, establecer rela-
ciones y restricciones, trabajar con conjuntos de datos o usar XML con ,ADO.NET.
Programacidn de bases de datos con Visual Basic .NET
B, Internet
En caso de encontrar algun problema con este libro o el CD-ROM que le acompa-
iia, el lector puede recurrir tanto a la editorial como directamente a1 autor.
Desde la Web de la editorial, en http: //www.AnayaMultimedia.com,pue-
de acceder a la secci6n Atencion al cliente para acceder a1 soporte tbcnico, asi como
a las secciones de Complementos y Fe de erratas.
Si desea ponerse en contact0 con el autor para plantear exclusivamente alguna
cuesti6n relativa a este libro, puede hacerlo a traves de la Web Torre de Babe2, en
http://www.fcharte.com.
n
Este libro estA dirigido a desarrolladores que necesitan utilizar 10s servicios de
ADO.NET para trabajar con bases de datos, documentos XML y, en general, cual-
quier origen de datos. Como programadores, el autor asume que ya se conocen 10s
terminos habituales en cualquier lenguaje de programach: variable, bucle, sen-
tencia, expresi6n condicional, compilaci6n, etc. No se asume, por el contrario, nin-
giin conocimiento relativo a1 trabajo con datos, campo que tambien cuenta con sus
propios conceptos y terminologia especifica.
A pesar de no ser dste un titulo dedicado a 10s fundamentos de tratamiento de
datos, tema sobre el que encontrard libros monogrdficos, en este capitulo se abor-
dan 10s elementos que podrian considerarse bisicos: ique es un DBMS o el lengua-
je SQL?, jcdmo se estructuran 10s datos en filas y columnas? o iqu6 es XML? son
algunos de 10s contenidos de este capitulo.
El objetivo no es otro que facilitarle 10s conocimientos indispensables, concep-
tos y tdrminos, para que pueda leer c6modamente 10s demis capitulos de este libro.
Posteriormente, dependiendo de su inter& y necesidades, puede recurrir a textos
que traten con mayor profundidad la teoria del tratamiento de bases de datos.
Origenes de datos
Los servicios de acceso a datos .NET, conocidos como ADO.NET, pueden ser
usados para operar sobre origenes de datos diversos, no exclusivamente sobre lo
1. Terminologia y conceptos
que se conoce como bases de datos. Un origen de datos puede ser una base de dat
SQL Server, un documento XML, una hoja de cdculo Microsoft Excel, el Direct
rio Activo de Windows 0, en general, cualquier recurso para el que exista un pr
veedor de datos .NET.
El origen d e datos, por tanto, es el recurso, ya sea local o remoto, del que va a e
traerse o en el que se va a introducir informacibn, teniendo un sentido mucho m
amplio que el de base de datos. En el texto encontrar6 ambas expresiones, la prim
ra cuando se quiera dar un sentido general y la segunda a1 hacer referencia concr
ta a un DBMS.
Utilizando el paradigma del origen de datos, sin asumir su localizacibn, estruct
ra ni naturaleza, ADO.NET es realmente un mecanismo de acceso a datos unive
sal. Esto tiene como ventaja fundamental el ahorro de trabajo para el desarrollado
a1 no tener que recurrir a sistemas diferentes dependiendo de 10s datos que se pr
tendan manipular o recuperar.
I l-----l
r
I
Figura 1.1. ALlO.NET actua como intermediario entre las aplicaciones y 10s posibles
origenes de datos, utilizando para ello diversos proveedores de acceso
Programacion de bases de datos con Visual Basic .NET
Los servicios de ADO.NET pueden utilizarse desde una aplicacion con interfaz
de usuario, un componente que se ejecuta en un servidor, un servicio Windows
o Web. En general, es posible recurrir a ADO.NET desde cualquier punto de
una aplicacion que se ejecute en un sistema donde este disponible la platafor-
ma .NET.
El origen de datos por excelencia es la base d e datos. Una base de datos puede
definirse como uno o mds archivos en 10s que se almacenan 10s datos y toda la in-
formaci6n que describe su estructura, fundamental para poder operar sobre ellos.
Las bases de datos pueden ser de distintas categorias, siendo el tip0 mds habitual
el de las bases de datos relacionales. Por otra parte, las bases de datos tambikn se
dividen en dos clases: bases de datos de escritorio y servidores de bases de datos.
Las primeras estiin dirigidas principalmente a usuarios con ciertos conocimientos
que le permiten crear y mantener sus estructuras de informacibn, raz6n por la cual
estas bases de datos cuentan con una interfaz de usuario bastante completa y ami-
gable. Es el caso de Microsoft Access, dBase o Paradox. Tambien se caracterizan
por no contar con un middleware que permita tener el software en una msquina y
10s datos en otra distinta, es decir, son bases de datos locales.
Se llama servidor de datos a una aplicaci6n que se encarga de manipular fisica-
mente 10s datos, ocupdndose de su almacenamiento y recuperaci6n de 10s archivos
en que se encuentran. De esta forma las aplicaciones no tienen que conocer la es-
tructura de dichos archivos, limitiindose a solicitar a1 servidor las operaciones que
quiere efectuar. Tambikn suele conocerse como servidor d e datos a1 ordenador en el
que se ejecuta dicha aplicaci6n.
Aunque una base de datos de escritorio o local puede colocarse en una unidad
compartida de red, facilitando el acceso a ella desde diferentes puestos, no es la
configuraci6n miis adecuada para construir un acceso multiusuario. En este caso
resultan mucho miis eficientes y seguros 10s servidores de bases de datos.
MS y RDBMS
Los servidores de bases de datos son sistemas de administraci6n de informa-
ci6n o DBMS, aplicaciones cuyo objetivo no es s610 almacenar y recuperar datos,
1. Terrninologia y conceptos
Tambien se conoce a 10s DBMS por sus siglas en nuestro idioma, SGBD, aun-
que su us0 es menos habitual.
Las bases de datos de escritorio, como 10s citados Access, dBase y Paradox,
no son servidores de datos y, por tanto, no pueden utilizarse en una arquitectu-
ra clientelservidor real, a pesar de la posibilidad indicada antes de colocar 10s
archivos de datos en una unidad compartida de red. La diferencia estA en que
cada maquina accederia a sus datos directamente, como si 10s archivos se en-
contrasen en ella, mientras que en una arquitectura cliente/servidor real el
Programacidn de bases de datos con Visual Basic .NET
cliente nunca accede directamente a 10s datos, sin0 que delega ese trabajo en
el servidor.
~
En la figura 1.2 puede ver representada una tipica configuracibn cliente / ser-
vidor. Concretamente aparece un servidor de datos, en la parte inferior, y varios
clientes, en la superior. Aunque en dicha imagen no se ha representado, se supone
que tanto clientes como servidor tienen sus respectivos paquetes de software ins-
talados.
Router 1
Servidor
de datos
, 1
aplicaciones Servidor
de datos
En este modelo 10s clientes no tienen acceso direct0 a 10s datos, trabajo que que
da en manos de 10s componentes que se ejecutan en el servidor de aplicaciones
Programacidn de bases de datos con Visual Basic .NET
Nosotros contamos con 10s servicios de ADO.NET para acceder a 10s origenes
de datos, utilizando para ello un modelo de objetos y componentes que tendra
ocasi6n de conocer en un capitulo posterior. ADO.NET, a su vez, precisa de otros
1 . Terminologi'a y conceptos
elementos para poder efectuar su trabajo, entre ellos 10s proveedores y 10s contro-
ladores.
Un proveedor ADO.NET es una implementacibn especifica de una serie de com
ponentes que facilitan el acceso a un determinado origen de datos. Visual Basic
.NET incorpora por defect0 dos proveedores de datos .NET: uno para SQL Serve
y otro capaz de emplear cualquier controlador OLE DB. Hay disponibles dos m6s
que instalar6 posteriormente, uno para Oracle y otro dirigido a1 us0 de un contro
lador ODBC.
Los proveedores .NET aparecen, desde el punto de vista del desarrollador, como
una serie de definiciones de clases alojadas en un Ambit0 con nombre o namespace
clases que pueden usarse para acceder a un determinado origen de datos. El pro
veedor de datos para SQL Server y el de Oracle son especificos, comunicindose
directamente con el software cliente de esas dos bases de datos sin intermediario
alguno. Los proveedores OLE DB y ODBC, por el contrario, son de tip0 genkrico
diseiiados para aprovechar todos 10s controladores que ya hay disponibles de esos
dos tipos.
Suponga que quiere, desde una aplicaci6n propia, recuperar datos de una hoja
de cilculo Excel o comunicarse con una base de datos IBM DB2 o InterBase. No
hay proveedores .NET especificos para estos tipos de datos, a1 menos no por el mo
mento, y por ello hay que recurrir a las soluciones genericas. Mediante un contro
lador OLE DB se puede acceder a Excel, y mediante ODBC a IBM DB2 o InterBase
En estos casos empleariamos un m6dulo o componente de software adicional a
proveedor OLE DB u ODBC: el controlador especifico del origen a1 que va a acce
derse.
En la figura 1.4 puede ver representados dos supuestos en 10s que un cliente
necesita acceder a dos origenes de datos diferentes: una base de datos SQL Serve
y una base de datos IBM DB2. En el primer caso, puesto que existe un proveedo
.NET especifico, el cliente tan s610 precisa el software cliente de SQL Server y ya
puede comunicarse, mediante una infraestructura de red, con el servidor. En e
segundo, por el contrario, no existe ese proveedor especifico, per0 si un controla
dor ODBC que sabe c6mo hablar con el software cliente de DB2. Utilizamos, po
tanto, el proveedor genkrico ODBC de .NET que, a su vez, empleari el controlado
ODBC adecuado.
Ni que decir tiene que el acceso mediante proveedores genkricos implica m6
carga de proceso y, por tanto, un menor rendimiento en la aplicaci6n. En alguna
ocasiones, sin embargo, puede ser la h i c a via para poder llegar a una cierta in
formaci6n.
L
Aparte de 10s componentes ADO.NET, que facilitan la comunicaci6n con 10
origenes de datos y ejecuci6n de ciertas operaciones, en ocasiones tambikn necesi
taremos conocer algun lenguaje especifico segun la naturaleza del origen de datos
Programacidn de bases de datos con Visual Basic .NET
Mediante XPath, por ejemplo, podria efectuarse una seleccidn de datos en un do-
cumento XML.
Aplicacion cliente
0,
I IBMDB2
El lenguaje de consulta de datos por excelencia entre 10s RDBMS es SQL, crea-
do hace algo m6s de veinte afios y conocido originalmente como SEQUEL. Realmen-
te SQL se compone de varios sub-lenguajes, principalmente DDL y DML. El primer0
de ellos se utiliza para definir las estructuras de 10s datos que se manipulan con el
1. Terrninologia y conceptos
I
segundo. Conocer el lenguaje SQL es fundamental para poder trabajar con bases
de datos, por ello en el siguiente capitulo podrd encontrar una introduccih a DDL
y DML.
Ademiis de para manipular la informacih, la mayoria de 10s RDBMS tambien
emplean SQL para otros fines como la implementacion de procedimientos almace-
nados. En realidad, cada fabricante de un product0 RDBMS cuenta con su propio
derivado de SQL para efectuar esas tareas. SQL Server, por ejemplo, cuentan con
el lenguaje T-SQL, mientras que Oracle utiliza PL/SQL. Tambibn encontrarii en el
capitulo siguiente una breve introduccih a dichos lenguajes.
~ - ~ ~ . - - _ _ _
Conjunto
de entidades
Figura 1.5. Conjunto de tres entidades con cuatro atributos cada una
. *
DO 10s
A1 conjunto de valores que puede tomar un atributo es a lo que se llama domi-
nio. El atributo ISBN del ejemplo mostrado en la figura 1.5, por poner un ejemplo,
tendr6 un dominio que limite la introducci6n a 13 caracteres ajustados a un cierto
formato. De manera aniloga, el atributo P a g i n a s contaria con un dominio que
tan s610 permitiese la introducci6n de valores numericos comprendidos entre 100
y 2000, por ejemplo.
Los dominios, cuando se definen asociados a columnas en un RDBMS, impiden
la introducci6n de valores incorrectos en la base de datos, asegurando asi la inte-
gridad de la informaci6n. A1 tiempo, se evita que la aplicaci6n tenga que estar com-
probando continuamente la validez de 10s valores introducidos por 10s usuarios.
Una restriccidn se define como el conjunto de reglas de validaci6n de un cierto
atributo, reglas que pueden ser mucho m i s complejas que un dominio. Mediante
una restricci6n es posible, por ejemplo, evitar que se introduzca en una tabla infor-
maci6n relativa a un elemento que no existe en otra. En realidad, 10s dominios son
un tip0 de restricci6n.
ldentidad de una
Por norma, las entidades suelen contar con un atributo a1 que se aplica una res-
tricci6n que le obliga a contener un valor unico entre el conjunto de entidades, uti-
lizindose como atributo de identidad de cada una de las entidades. Es el clisico
cddigo que se asocia a las filas, normalmente un numero consecutivo generado por
la propia base de datos, y que permite identificarlas de manera unica.
Que las entidades tengan un atributo de identidad es algo indispensable en 10s
RDBMS, ya que facilita el establecimiento de relaciones entre distintos conjuntos
de entidades y hace posible la integridad referencial mediante restricciones de cla-
ves externas. Ademis, las reglas de normalizacion comentadas brevemente m i s
adelante exigen la existencia de ese atributo de identidad.
ILf 1. Terrninologia y conceptos
conjuntos de enti
Los conjuntos de entidades que conforman una base de datos, en forma de tablas,
generalmente guardan ciertas relaciones entre ellos. Las reglas de normalizaci6n
de las bases de datos relacionales, que conocer6 b6sicamente en un punto poste-
rior, persiguen evitar la repetici6n de datos en las tablas a fin de ahorrar espacio.
No tiene sentido, por ejemplo, que en el conjunto de entidades de la figura 1.5 se
repita el nombre de la editorial en cada entidad.
En la figura 1.6 se pueden ver dos conjuntos de entidades: uno relativos a libros
y otro a editoriales. Observe que el segundo atributo de cada libro ahora no es el
nombre de la editorial, sin0 un numero que la identifica. Ese numero es el atributo
identidad de las entidades del segundo conjunto.
contrario, nos encontrariamos con el segundo caso, por cada fila de la editorial de
tablas tendriamos multiples filas de la tabla de libros que le corresponden, en este
ejemplo concreto tres.
Anaya M u l t i m e d i a
O'ReiLly
A1 trabajar con tablas de tamafio considerable, con muchos miles 0, incluso, mi-
llones de filas, el proceso de recuperaci6n de datos puede verse afectado de mane-
ra considerable. Es 16gico si tenemos en cuenta que para, por ejemplo, encontrar
todos 10s libros de una editorial, seria precis0 recorrer la tabla de libros completa,
de principio a fin.
Un mecanismo comun para acelerar esa operaci6n son 10s indices. Un indice es
una lista de claves con una estructura tal que el servidor puede realizar busquedas
de forma muy ripida en ella.
Las claves pueden estar formadas por el contenido de una o varias columnas de
una tabla. Ademis de acelerar la busqueda de informacih, un indice tambi6n pue-
de ser utilizado para establecer el orden en el que se almacenarin las filas en una
tabla.
Cada vez que se inserta, modifica o elimina una tabla de la cual depende uno o
varios indices, el servidor tiene que actualizar no s610 la tabla de datos sin0 tam-
bi6n todos 10s indices que existan a fin de que Sean consistentes con la informaci6n
actual. Es ficil deducir que cuintos m i s indices existan m i s tiempo seri necesario
para efectuar cualquiera de esas operaciones.
Prograrnacidn de bases de datos con Visual Basic .NET
Cada entidad debe contar siempre con un atributo identidad que actue co-
mo clave primaria y unica, facilitando de esa manera la identificacih inequi-
voca de cada una de las filas de una tabla. TaI y como antes se indicaba, el
atributo identidad es un dato, real o creado a prop6sit0, que nunca se repite
entre las entidades.
Otra norma comun del proceso de normalizacih es evitar la duplicidad de
datos, tanto dentro de una misma tabla como entre las tablas que componen
la base de datos. Es lo que ocurria en el ejemplo representado en la figura 1.5
y que hemos solucionado en la figura 1.6 normalizando la base de datos.
Aunque seguramente 10s dos aspectos mas importantes del proceso de norma-
lizaci6n Sean kstos, existen otros que tambikn deberian considerarse para conse-
guir el objetivo de un disefio racionalizado y 16gico. Es importante que no existan
relaciones demasiado complejas entre tablas que provoque dificultades a la hora
de recuperar informacion, en forma de consultas dificiles de expresar por parte
del programador o usuario y de ejecutar por parte del RDBMS. Otra regla indica
que todos 10s atributos que se empleen para establecer relaciones entre tablas de-
ben ser claves o formar parte de un indice para acelerar su proceso.
-~ - __-
_ _ ~ _ _ _ _ _ _ _ _______-__-.-----_
~ - _I____ _ _ _ _ I _ ___-
^____l___l_ll _
_______I__ _ _ _ ~ - I ~ ~
A1 operar sobre un RDBMS del tipo Oracle, SQL Server, DB2, Sybase o InterBase,
10s que podriamos considerar servtdores de datos, todas las actuaciones que impli-
quen manipulacih de la informacih, no solo recuperaci6n de datos, tienen lugar
en el Qmbito de una transacctdn. Esto es especialmente cierto en aquellos casos en
10s que la informaci6n manipulada se aloja en dos o mas tablas y, por tanto, podria
generarse una inconsistencia entre 10s datos.
1. Terrninologia y conceptos
Suponga que crea una aplicaci6n para una entidad bancaria en la que el usuario,
por ejemplo el cajero de una oficina, introducir6 datos sobre operaciones banca-
rias. Atendiendo a un cliente que quiere efectuar una transferencia desde su cuen-
ta a la de un proveedor, el cajero introduce 10s dos c6digos de cuenta y el importe
a transferir, entre otros datos. A1 pulsar un bot6n su aplicaci6n deduce el importe
de la cuenta del cliente y, cuando va a sumarlo a la cuenta del proveedor, se pro-
duce un fallo en el sistema. iQu6 ha ocurrido con la operacibn? En ese momento ya
no est5 el dinero en la cuenta del cliente, per0 tampoco en la del proveedor. Sim-
plemente ha desaparecido o quiz5 est6 en el limbo.
Obviamente, esa situaci6n no deberia darse nunca. A1 iniciar las operaciones
sobre la base de datos la aplicaci6n deberia iniciar una transacci6n. h a asegura
que 10s datos que se manipulen no son escritos de manera inmediata en la base de
datos, sino en un espacio temporal. S610 cuando se han finalizado 10s cambios en
todas las tablas afectadas se termina la transacci6n, momento en el que dichos cam-
bios se confirman.
Para que este sistema sea realmente util es necesario que el sistema de transac-
ciones del RDBMS cumpla con las propiedades conocidas como ACID:
0 La atornicidnd de la transacci6n hace que todas las operaciones que compren-
de Sean vistas por el RDBMS como una sola, de tal manera que o se efectcia o
se rechaza completa, no existiendo la posibilidad de que el trabajo quede a
medias.
0 Mediante la consistencia se garantiza el cumplimiento de las reglas que lle-
ven asociadas las operaciones introducidas en la transaccibn, tales como res-
tricciones, ejecuci6n de desencadenadores, etc.
Que una transacci6n tenga entre sus propiedades el aislamiento implica que
las operaciones intermedias que se efectuen, antes de finalizar la transacci6n,
no son visibles para nosotros y, an5logamente, las realizadas en esta transac-
cion no Sean visibles en otras hasta que se confirme. Asi se consigue una in-
dependencia total en el trabajo de multiples transacciones concurrentes.
0 Por ciltimo tenemos la durabilidad o persistencia, la propiedad que da la ga-
rantia de que la transaccibn, una vez concluida, no se perder5 a pesar de 10s
problemas posteriores que pudiesen encontrarse.
En el supuesto anterior de la transferencia bancaria, si se produjese un fallo en
el punto indicado la transacci6n no se finalizaria y quedaria en un espacio conoci-
do como limbo, de la cual se recuperaria posteriormente.
Las transacciones se confirman o se rechazan. La confirmacidn de una transac-
ci6n implica su finalizaci6n, asi como la conversi6n en definitivos de 10s cambios
provisionales que se hubiesen efectuado. De rechazarse, la transaccih dejaria en su
estado original todos 10s datos afectados, finalizando tambi6n la transaccion.
Con ADO.NET, como veremos en su momento, generalmente no tendremos
que preocuparnos de iniciar y finalizar las transacciones de forma explicita, ya que
hay un mecanismo que se encarga de hacer ese trabajo por nosotros.
Programacidn de bases de datos con Visual Basic .NET
XML
Seguramente ya sepa qu6 es XML y c u d es su finalidad, ya que se trata de un
lenguaje que en 10s ultimos afios ha encontrado aplicaci6n en prscticamente todos
10s campos de la informAtica. A1 trabajar con ADO.NET no s610 podremos operar
sobre documentos XML sin0 que, ademds, 10s conjuntos de datos en ADO.NET se
almacenan internamente en dicho formato.
XML es un lenguaje que se centra en la definici6n de la estructura de 10s datos,
en contraposici6n a otros, como es el caso de HTML, que se ocupa no de 10s datos en
si sin0 de su representaci6n visual. En XML es posible definir marcas propias se-
gun se precise, facilitando asi la creaci6n de estructuras de informaci6n a medida.
El beneficio es que XML se almacena y transfiere a trav6s de redes no en un forma-
to binario, como venia siendo habitual en cualquier medio para el almacenamiento
de datos, sin0 como texto simple, facilitando asi la comunicaci6n entre aplicacio-
nes y sistemas sin importar el tip0 de procesador, sistema operativo o lenguaje de
programaci6n empleados.
A pesar de su naturaleza, XML es un formato para el almacenamiento de datos
con definici6n implicita, no para la presentaci6n de esos datos. Es muy fdcil, no
obstante, definir una hoja de estilo XSL y aplicarla a un documento XML para ob-
tener una representach visual de la informaci6n. De la misma forma, tambi6n se
pueden definir esquemas XSD para asegurar que la estructura de 10s documentos
es correcta.
En la plataforma .NET existen servicios especificos para trabajar con documen-
tos XML. Como veremos posteriormente, tambien podemos actuar sobre ellos me-
diante ADO.NET, como si fuesen origenes de datos locales.
0 DML: Es la parte m6s conocida del lenguaje SQL, a1 formar parte de 41 todas
las sentencias de manipulaci6n de datos: extracci6n de informacibn, actuali-
zaci6n y eliminacih. Tebricamente, y asumiendo que existe un DBA que se
ocupa del RDBMS, 10s programadores tan s61o tendrian que conocer DML
para efectuar su trabajo.
0 DDL: Con las sentencias DDL no se manipulan 10s datos propiamente di-
chos, sino la informacih de su estructura. Con las sentencias DDL pueden
definirse las columnas de una tabla y sus atributos, eliminar o crear un indi-
ce, etc.
0 DCL: Mucho menos conocido que 10s dos anteriores, este lenguaje se compo-
ne de sentencias especificas para garantizar la seguridad de acceso a 10s da-
tos, facilitando la gestion de usuarios y el otorgamiento o denegaci6n de 10s
permisos necesarios para operar sobre cada elemento de la base de datos.
caciones. En 10s puntos siguientes, no obstante, tambien encontrari una r6pida in-
troducci6n a algunas de las sentencias de DDL y DCL.
Puede usar una base de datos de escritorio, por ejemplo Microsoft Access (v6a-
se figura 2.1), ya que permiten la ejecucion de un subconjunto del lenguaje SQL, o
bien la utilidad de SQL interactivo del RDBMS con que cuente. Esta puede ser el
Analizador de consultas SQL de SQL Server (v6ase figura 2.2), el Interactive SQL
de InterBase (v6ase figura 2.3) o bien el SQL*Plus Worksheet de Oracle 8i (v6ase
figura 2.4). En cualquier caso, no entraremos en este momento en detalles sobre
c6mo usar una herramienta u otra, en el pr6ximo capitulo conocera algunas de ellas,
sino que nos centraremos en la sintaxis de SQL, sin mbs.
Figura 2.1. Desde Microsoft Access es posible definir consultas mediante asistentes,
per0 tambien pueden escribirse de forma manual
Antes de poder manipular datos mediante DML, es necesario que dichos datos
existan ya en la base de datos y, para ello, es precis0 definir las estructuras que 10s
Prograrnacidn de bases de datos con V i s u a l Basic .NET
Conexmes 1
Figura 2.3. Aunque con un nombre diferente y sobre otro RDBMS, el Interactive SQL
de InterBase es una herramienta similar a la de SQL Server
2. S Q L y sus dialectos
Mediante DDL es posible crear una base de datos, crear las tablas definiendo
las columnas que t e n d r h , crear indices y vistas y, por supuesto, modificar y eli-
minar todos esos elementos. Los comandos DDL son tres:
CREATE: Se utiliza para crear bases de datos, tablas, indices, desencadena-
dores, procedimientos almacenados y vistas, segun la palabra clave que se
indique a continuacih. Dependiendo del caso aceptar6 m6s o menos par&-
metros adicionales.
DROP: Acepta las mismas palabras clave que el comando CREATE, si bien la
finalidad es eliminar el elemento indicado en lugar de crearlo.
ALTER: Con este comando es posible modificar algunas de las estructuras de
una base de datos. No acepta todas las palabras clave de 10s dos comandos
anteriores, solo parte de ellas. Las vistas, por ejemplo, pueden crearse y eli-
minarse, per0 no modificarse.
Dependiendo del elemento que se pretenda crear, eliminar o modificar, tras el
comando ird una de las palabras clave siguientes:
DATABASE: Base de datos.
TABLE: Tabla.
Programacio'n de bases de datos con Visual Basic .NET
0 VIEW: Vista.
0 PROCEDURE: Procedimiento almacenado.
0 TRIGGER: Desencadenador.
0 INDEX: indice.
Los pardmetros adicionales dependerhn del comando y, en ocasiones, del RDBMS
sobre el que est4 trabaj6ndose.
CREATE DATABASE n o r n b r e _ b a s e _ d e - d a t o s
El nombre de la base de datos puede ser un nombre 16gic0, caso en el cual exis-
tir6n opciones adicionales para indicar la localizacih y nombre fisico de 10s archi-
vos donde ser6 alojada, o bien ser una especificacion de nombre de archivo en si
mismo, segun el RDBMS con que trabajemos.
Una vez que ya tenemos la base de datos creada, y estamos conectados a ella, el
siguiente paso 16gico es crear las tablas que alojar6n 10s datos, definiendo 10s atri-
butos de cada una de dichas columnas. A1 tiempo, tambi4n es posible establecer
las restricciones para cada una de las columnas, asi como la creaci6n de claves pri-
marias.
La sintaxis general para la definici6n de una nueva tabla en una base de datos
es la siguiente:
2. S Q L y sus dialectos
nonibre c o l u m n a tip0 o p c i o n e s ,
~
...
I
NOT NULL:Indica que la columna no puede quedar sin valor. Hay que tener
en cuenta que una cadena de caracteres vacia o un cero no es igual a NULL,
por lo que una columna que tenga esta restriccih podria tomar perfectamen-
te uno de esos valores.
0 UNIQUE: Esta restricci6n impide que en la columna asociada puedan existir
dos valores identicos 0,dicho de otra manera, garantiza que 10s valores in-
cluidos en esta columna seran tinicos.
PRIMARY KEY: Establece la columna a la que acompafia como clave prima-
ria o principal de la tabla, es decir, como atributo de identidad de cada fila.
Programacion de bases de datos con V i s u a l Basic .NET
Esto suele conllevar el hecho de que 10s valores de dicha columna deban ser
unicos.
0 FOREIGN KEY:Define una colurnna como clave externa, que hace referencia
a una clave primaria de otra tabla.
Las opciones PRIMARY KEY y FOREIGN KEY pueden tanto seguir a una colum-
na como disponerse a1 final de la lista de columnas, caso en el cual se indicaria en-
tre parhtesis, detras de KEY, el nombre de la columna o columnas que actuarian
como clave primaria o clave externa. En este ultimo caso, hay que aiiadir el aparta-
do REFERENCES ( col), donde col seria la referencia a la tabla y columna externa.
A continuacibn tiene un ejemplo de creaci6n de una tabla simple:
Tenemos una columna que actua como clave principal, identificando a cada una
de las filas que pudieran existir en la tabla. Se ha utilizado una colurnna INTEGER
como clave unica en lugar de la columna 1S BN que, como puede verse, alberga va-
lores unicos. Para 10s RDBMS, sin embargo, resulta mucho mas fdcil gestionar una
clave que es un numero que una cadena de 13 caracteres. Aunque parezca redun-
dante aiiadir una columna como identidad de cada fila, en realidad estd ahorrdndo-
se espacio y se mejora el rendimiento.
Las columnas T i t ul o y Auto r tienen una longitud variable, aunque con un
mdximo, en contraposici6n a ISBN que siempre tendra 13 caracteres. El us0 de
VARCHAR tambien ahorra espacio en la base de datos, a1 ocupar tan s610 el espacio
necesario para almacenar cada valor en lugar de asignar el mdximo posible.
Por ultimo, encontramos la definici6n de una clave externa, llamada Edito-
rial en esta tabla, que hace referencia a la columna IDEditorial de la tabla
Editoriales. Lbgicamente, dicha tabla deberd existir y la columna IDEditorial
seria su clave primaria.
Debe tener en cuenta que, dependiendo del DBMS que emplee, para crear una
tabla puede necesitar ciertos permisos o privilegios. De no contar con ellos, la
ejecucion de una sentencia como la anterior provocaria un error. En algunos
DBMS, ademas, debera preceder el nombre de la nueva tabla con el esquema
donde quiera crearla si es que dicho esquema no es el asumido por defecto.
2 . S Q L y sus dialectos
Otra posibilidad, a la hora de crear una tabla en una base de datos, consiste
en hacerlo a partir de 10s datos que ya existen en otra tabla. En este caso el
comando CREATE TABLE nombre iria seguido no de una lista de columnas,
tipos y opciones, corno en el ejemplo anterior, sino de una consulta SQL que
recuperaria de otra tabla o tablas 10s datos con 10s que se generaria la nueva
tabla.
Las modificaciones a una tabla pueden ser de distintos tipos, desde aiiadir o
eliminar una columna o una restriccibn hasta modificar la definicih original de la
columna para cambiar el tipo. En cualquier caso, la sentencia la iniciaremos con
ALTER TABLE N o m b r e T a b l a , tras la cual dispondremos la palabra ADD, para
aiiadir un nuevo elemento; ALTER, para modificarlo, o DROP si queremos eliminar-
lo. Por ejemplo:
Hay que tener en cuenta que la modificacion del tip0 de una columna puede
irnplicar una perdida de datos, algo que es obvio si la columna se elimina.
Si deseamos eliminar una tabla completa, no tenemos m& que usar la sintaxis
mostrada en el ejemplo siguiente:
Aunque las tablas son el centro de cualquier base de datos, a1 ser fisicamente
las que alojan la informacih, t a m b i h existen otros elementos de us0 comun, en-
tre ellos 10s indices y las vistas.
Para crear un indice utilizaria la siguiente sintaxis:
C R E A T E I N D E X I n d I S B N ON Libros ( I S B N )
C R E A T E V I E W NombreVista AS Consulta
C R E A T E V I E W LibrosEditorial A S
SELECT Editorial.Nombre, Libros.Titulo
FROM Editorial, Libros
WHERE Editorial.IDEditorial=Libros.Editorial
2. S Q L y sus dialectos
El resultado, a1 ejecutar esta vista, seria una tabla temporal con dos columnas,
una con el nombre de la editorial y otra con el titulo del libro, y tantas filas como
combinaciones de editoriales y libros existan en las tablas.
La consulta asociada a una vista puede modificarse con la sentencia ALTER
VIEW, por ejemplo:
ALTER VIEW L i b r o s E , J i t o r i a l A S
S E L E r T E d i t , - > r i a l . N s r n l n r e , L i b r o s . ISBN
FROM E d i t o r i a l , L i b r c - I S
W H E R E E d i t o r 1a 1 .1DEd I t~c .
r i a 1=Lib r o s EIJ i t~o r i a 1
Aqui hemos modificado la vista anterior para que, en lugar del titulo de 10s li-
bros, se incluya el ISBN.
Asimismo, la eliminaci6n de una vista es tan simple como ejecutar la sentencia
DROP VIEW NombreVista.
Nota
Segun se indicaba al inicio de este punto, dedicado a DDL, 10s mismos coman-
dos CREATE, ALTER y DROP pueden utilizarse tambien para crear desenca-
denadores, procedimientos almacenados y otros elementos. Las posibilidades
y sintaxis, en estos casos, varian en mayor medida de un DBMS a otro. Para
crear un desencadenador o procedimiento almacenado, por ejemplo, suele ha-
cerse us0 del lenguaje especifico del RDBMS para efectuar la implernentacion
de una cierta Iogica.
Si con DDL definimos las estructuras para el almacenamiento de 10s datos, con
DML podremos manipular 10s datos propiamente dichos, efectuando consultas
para recuperar datos, modificaciones, borrados, etc.
Las operaciones fundamentales de manipulacih de datos son cuatro y, conse-
cuentemente, cuatro 10s comandos DML que necesitaremos para poder llevarlas a
cabo:
0 SELECT: La sentencia DML por excelencia. Se utiliza para ejecutar consultas
de recuperacih de datos.
0 I N S E R T : Su finalidad es insertar nuevas filas en una tabla.
0 UPDATE: Con este comando es posible cambiar la informacih alojada en
una o m i s filas.
DELETE: Se utiliza para eliminar una 0 m6s filas.
Programacidn de bases de datos con Visual Basic .NET
__ __ ___ I_ --
Si creamos una aplicaci6n para que 10s usuarios puedan trabajar sobre una base
de datos, una operaci6n biisica es la inserci6n de nuevos datos. De hecho, en prin-
cipio ser6 la unica opci6n disponible a menos que las tablas de datos sobre las que
se trabaje tengan ya informaci6n previamente. La sintaxis de la sentencia I N S E R T
es la siguiente:
INSERT I N T O L i b r o s V A L I J E S
(1, ' n 4 - 4 1 5 - 1 ? 5 1 - 1 ' ,
' P r o g r a m a c i h n con V i s u a l Basic .NET',
' F r a n c i s c o Charte O j e d a ' , 3 )
En caso de que desee introducir datos en menos columnas de las que existen en
la tabla, deberia especificar las columnas de destino detr6s del nombre de la tabla,
entre parhtesis. Por ejemplo:
El resto de las columnas de esa fila quedarian con el valor NULL, siempre, por
supuesto, que sus restricciones no lo impidan.
En el caso de que se viole alguna restriccibn, como que un valor no sea unico en
una columna que debe serlo o que se entregue como una clave externa un valor
que no se encuentre en la tabla de destino, la inserci6n no se efectuari y generari
un error.
2. S Q L y sus dialectos
SELECT T i t u l o , A u t o r FROM L i b r o s
Esta consulta retornaria el titulo y autor de todas las filas existentes en la tabla
L i b r o s . Si queremos obtener todas las columnas de la tabla, sin necesidad de es-
pecificar el nombre de cada una, podemos sustituir la lista que sigue a la palabra
S E L E C T por un asterisco:
SELECT * FROM L i b r o s
CI
_ I ~ I ~ _ _ _ _ I _ . _ _ .~
_ _ ~ -
_ I _ _ I _ _ _ _ I__-_-
__
Como va a ver en 10s puntos siguientes, a la hora de establecer condiciones y,
especialmente, cuando se usa m6s de una tabla para generar la consulta, es necesa-
rio hacer referencia alas columnas utilizando la notaci6nNombreTabla. N o m b r e -
C o l u m n a . Esto puede hacer algo farragosa la codificaci6n de consultas complejas,
repitiendo el nombre completo de la tabla una y otra vez.
Afortunadamente, la sentencia SELECT nos permite asociar un alias a cada una
de las tablas participantes en la consulta. Para ello no tenemos m i s que poner di-
cho alias tras el nombre original de la tabla, a continuaci6n de la palabra FROM,
pudiendo usar el alias en toda la consulta. Por ejemplo, en la siguiente consulta se
asocia el alias L a la tabla L i b r o s :
En este caso concreto no tiene mucho sentido ya que, a1 participar una sola
tabla en la consulta, no tenemos porqu6 usar la notaci6n L . I S BN para seleccionar
la columna ISBN, hubiera bastado con facilitar directamente el nombre de la co-
lumna. Encontrard una mayor aplicaci6n al us0 de 10s alias de tablas en 10s puntos
siguientes.
Seleccicin de Eilas
Indicar en la consulta qu6 columnas deseamos incluir en el conjunto de resulta-
dos es bastante sencillo, ya que el numero de columnas con que cuenta una tabla
suele ser pequeiio y, por tanto, podemos indicar 10s nombres de cada una de ellas
tras la palabra SELECT.
Para seleccionar un determinado conjunto de filas no es posible utilizar una tkc-
nica similar, primer0 porque las filas no tienen nombres, sin0 que contienen va-
lores, y segundo porque, a diferencia de columna, una tabla puede alojar miles o
incluso millones de filas. Por ello la soluci6n tiene que ser totalmente diferente pe-
ro, como programadores, nos debe resultar relativamente fdcil comprenderla ya
que est6 basada en la evaluaci6n de expresiones condicionales.
Aparte de la cl6usula FROM,unica obligatoria y con la cual se indican las tablas
de las que va a recuperarse la informacibn, la sentencia S E L E C T puede contar,
opcionalmente, con varias mds. Una de ellas es la cldusula WHERE, encargada de
aplicar uno o m6s condicionales basdndose en 10s cuales se filtrardn las filas a de-
volver. La sintaxis de la consulta seria la siguiente:
SELECT C o l u r n n a s FROM Tablas WHERE C o n d i c i j i - j
Condicionalcs complcjos
Ademds de condicionales relativamente simples, en 10s que se compara si el va-
lor de una columna es igual, mayor o menor que otro valor dado, en la cldusula
2. S Q L y sus dialectos
WHERE pueden emplearse elementos adicionales que nos permiten crear condicio-
nales realmente complejas. A 10s operadores relacionales cldsicos hay que aiiadir
otros, como I N , LIKE y BETWEEN, mucho m6s flexibles.
Mediante el operador IN es posible crear una expresion que serd cierta en caso
de que el valor de la columna indicada a la izquierda contenga uno de 10s valores
delimitados entre parhtesis, a la derecha del operador. Por ejemplo:
SELECT ISBN, T i t u l o
FROM L i b r o s
WHERE A u t o r
I N ( ' B i l l Gdtes', ' P a u l Allen', 'Steven J o b s ' )
En esta consulta se seleccionan todos 10s titulos escritos por 10s tres autores in-
dicados entre parhtesis, evit6ndonos asi la construccion de tres condicionales con
el operador = unidos mediante AND.
Con el operador LIKE podemos efectuar comparaciones no absolutas entre 10s
valores de una columna y un valor dado 0, dicho de otra forma, facilita la busque-
da de un cierto patron entre 10s valores de una columna.
Tras el operador L I K E debemos facilitar, entre comillas simples, el patron a
buscar. Por ejemplo:
SELECT ISBN, T i t u l o
FROM L i b r o s
WHERE T i t u l o LIKE ' V i s u a l % '
En este caso obtendriamos la lista de todos aquellos libros cuyo titulo comience
con Visual, sin necesidad de especificar el titulo completo.
Por ultimo tenemos BETWEEN, mediante el cual es posible especificar un rango
de valores en el cual deberd encontrarse una cierta columna para ser incluida en el
conjunto de resultados. Por ejemplo, si queremos obtener todos aquellos libros cu-
yo precio se encuentre entre 30 y 50 euros podemos utilizar una consulta como la
siguiente:
SELECT ISBN, T i t u l o
FROM L i b r o s
WHERE P r e c i o BE,TWEEN 3 0 AND 5 0
S E L E C T 1S BN , 'Tit 111o
FROM Libros
WHERE A u t o r
I N ('Bill Gates', 'Paul A l l e n ' , 'Steven Jobs')
AND Precio BETWEEN 3 0 AND 5 0
AND T i t u l o L I K E 'Visual%'
Programacidn de bases de datos con Visual Basic .NET
El conjunto de datos obtenido estaria formado por todos aquellos libros que,
escritos por Bill Gates, Paul Allen o Steven Jobs, costasen entre 30 y 50 euros y,
adem&, su titulo comenzase con la palabra V i s u a l .
Con esta consulta obtendriamos una lista completa de todas las filas que hay en
la tabla Libros ordenadas alfabeticamente por el contenido de la columna Titu-
l o . El orden seria de menor a mayor, es decir, de la A a la Z . Podemos alterar el
orden mediante las palabras DESC y ASC, segun deseemos un orden descendente o
ascendente.
Hasta ahora, en las consultas mostradas como ejemplo en 10s puntos anteriores,
siempre hemos seleccionado como resultados una serie de columnas existentes en
las tablas. Tambien existe la posibilidad de introducir expresiones, usando como
operando el valor de una o varias columnas, y funciones de resumen o agregacidn.
Para obtener, aparte de las columnas que nos interesen, datos obtenidos a par-
tir de algun ciilculo u operacih, tan s610 tenemos que incluir la expresih apropia-
da como si de una columna m6s se tratase. Por ejemplo:
Con esta consulta se obtendria una lista de titulos de libros y una segunda co-
lumna que tendria el precio m6s un 4 por ciento. Dicho valor se obtendria como
resultado de la consulta, per0 no afectaria en absoluto a1 contenido de la tabla
Libros.
Si lo que necesitamos no es operar sobre una cierta columna de una fila, como
en este caso, sin0 sobre todas las columnas recuperadas a partir de la consulta, po-
demos utilizar las funciones de agregaci6n. Las de us0 m6s corriente son:
0 COUNT ( ) : Cuenta el numero de filas obtenidas como resultado.
0 SUM ( ) : Suma 10s valores de la columna indicada de todas las filas del con-
junto.
2. S Q L y sus dialectos
AVG ( ) : Efectua una media sobre 10s valores de la columna indicada de todas
las filas del conjunto.
MAX ( ) : Halla el valor maxim0 de la columna indicada entre todas las filas
del conjunto.
M I N ( ) : Halla el valor minimo de la columna indicada entre todas las filas
del conjunto.
Cuando en una sentencia SELECT aparece una o m6s funciones de agregacibn,
las unicas columnas adicionales que pueden incluirse son las utilizadas para efec-
tuar agrupamientos, segun se Vera en el punto siguiente. El siguiente es un ejem-
plo de us0 de estas funciones:
El resultado obtenido seria una sola fila conteniendo el numero total de filas de
la tabla Libros, puesto que no se ha aiiadido una cliusula WHERE, asi como el
precio del libro mas barato y el del m6s caro.
S E L E C T Editorial, COUNT(Precio),
MINiPrecio), MAXiPrecio)
FROM Libros
G R O U P BY Editorial
En este caso no se obtendria una sola fila de resultados, como en el punto pre-
vio, sin0 una fila por editorial. Ademas, cada fila contendria el numero de titulos
de esa editorial, asi como 10s precios minimo y mdximo de 10s titulos de esa edi-
torial. Un resultado asi, que es ejecutado en el RDBMS y devuelto a la aplicacih,
puede ahorrarnos muchas sentencias de programa Visual Basic.
Enlnc
En todos 10s ejemplos previos se ha operado exclusivamente sobre una tabla de
la base de datos. No es extrafio, sin embargo, que sea precis0 recuperar columnas
de dos o m6s tablas, por ejemplo una lista de editoriales y 10s libros correspondien-
tes a cada una, la informacih de un pedido y las lineas asociadas, etc.
Tras la cl6usula FROM puede aparecer cualquier numero de tablas, y tras SELECT
todas las columnas que se necesiten de esas tablas. Para poder asociar 10s datos de
las distintas tablas, y componer adecuadamente cada fila del conjunto de datos re-
Programacidn de bases de datos con Visual Basic .NET
sultante, es preciso crear un vinculo entre las distintas tablas. Con este fin se uti-
lizan las claves primarias y externas que se definieron previamente, enlaz6ndolas
mediante un condicional en el apartado WHERE.
Suponga que desea obtener una lista con el nombre de cada editorial y 10s titu-
10s que le corresponden. La consulta podria ser la siguiente:
co
- _ _ _ ~ ~ _ _ I _ _ I _~ __II_ ~~ --
Las sentencias SELECT pueden anidarse, dando lugar a lo que se conoce como
subconsultas. Primero se ejecuta la consulta que est6 en el nivel m6s interior (apare-
ce despues en la sentencia completa), obteniendose un conjunto de resultados que,
en lugar de devolverse directamente, se entrega a la consulta del nivel exterior pa-
ra que efectue el proceso apropiado. Este proceso se repite las veces que sea preciso
hasta llegar a1 SELECT m6s exterior, el que aparece en primer lugar en la senten-
cia, momento en que se devuelven 10s resultados.
Suponga que desea obtener una lista de todos aquellos libros cuyo precio es su-
perior a la media. iC6mo se expresaria esa consulta? Primero es necesario obtener
la media del precio y, a continuacih, utilizarla como resultado para ejecutar otra
consulta. En lugar de utilizar una variable intermedia y ejecutar dos consultas,
resulta mucho m i s efectivo utilizar una sentencia como la siguiente:
Por ejemplo:
S E L E C T T i t u l o , P r - e c i o * l . 0 4 FROM
(SELECT T i t u l o , P r e c h , E d i t o r i a l
FROM L i b r o s
WHERE E d i t r ) r i a l =
( S E L E C T I d E d i t o r i a l FROM E d i t o r i a l e E
WHERE, N o m h r e = ' A n d y a M i i l t i r n e d i a ' )
..
En este caso se ejecuta primer0 la sentencia S E L E C T I d E d i t o r i a l . con el
fin de obtener el identificador de una cierta editorial. Ese identificador se utiliza
para recuperar el titulo, precio y editorial de todos 10s libros de esa editorial, re-
sultado que, a su vez, es usado por otro S E L E C T para obtener el titulo y un c6lculo
sobre el precio.
Una vez insertados en una tabla, 10s datos pueden consultarse tantas veces co-
mo se precise e, igualmente, es posible modificarlos si es necesario. En este caso la
sentencia a utilizar ser6 UPDATE, con la sintaxis siguiente:
1J P DATE N o r r i h r e T a b 1a
S E T Columna=Valor, C o l u m n a = V a l o r ...
Hay que tener en cuenta que, de no facilitar una cliusula WHERE con un condi-
cional, la sentencia de actualizacih afectari a la tabla completa. La ejecuci6n de la
sentencia siguiente, por ejemplo, asignaria el valor 30 a1 precio de todos 10s libros
existentes en la tabla L i b r o s :
U P D A T E Libros
SET P r e c i o = 3 0
IJPDATE L i b r o s
SET P r e c i o = 3 0
WHERE I S B N = ' 8 4 - 4 1 5 - 1 3 5 1 - 1 '
Programacidn de bases de datos con Visual Basic .NET
DELETE Libros
WHERE ISBN='R4-415-1351-1'
Como se indicaba a1 inicio del capitulo, DCL resulta mucho menos conocido
para 10s desarrolladores que DML y DDL, especialmente porque las tareas para
las que se utiliza recaen siempre en un DBA, encargado de gestionar 10s usuarios
que pueden acceder a la base de datos y otorgarles o denegarles la operacidn sobre
sus tablas.
Las dos sentencias m6s conocidas de este grupo son GRANT y REVOKE. Con la
primera se otorga un cierto permiso, mientras que con la segunda se deniega. Los
permisos pueden ser globales o muy concretos, por ejemplo la insercidn o borrado
de una tabla o la modificacidn de ciertas columnas. El destinatario del otorgamiento
o la denegacidn es un perfil o una cuenta de usuario, segun 10s casos. Estos perfiles
y cuentas tambien pueden crearse mediante DCL, con sentencias del tipo CREATE
U S E R y CREATE ROLE, si bien la sintaxis suele diferir entre distintos DBMS.
Suponiendo que estuvi4semos trabajando con SQL Server y dese6semos per-
mitir la seleccidn e insercidn, per0 no la modificacidn ni el borrado, sobre la tabla
Libros a un usuario llamado Operador, podriamos usar las siguientes senten-
cias DCL:
GRANT SELECT, INSERT
ON L i h r o s T O Operador
2. S Q L y sus dialectos
REVOKE U P D A T E , DELETE
ON L i b r o s FROM O p e r a d o r
El lenguaje SQL, como ha podido ver desde el inicio de este capitulo, est6 orien-
tad0 a1 trabajo con conjuntos de datos, facilitando la selecci6n y modificaci6n de
manera flexible y potente. Efectuar un trabajo similar desde Visual Basic, proce-
sando 10s datos de manera individual, conllevaria una carga mucho mayor para
nuestras aplicaciones.
A pesar de todo, SQL tiene sus limitaciones 0, simplemente, no estaba pensado
originalmente para las necesidades que han surgido con posterioridad. Una de
esas necesidades es la incorporaci6n en el propio DBMS de parte de la 16gica de
proceso de 10s datos, en forma de desencadenadores y procedimientos almacena-
dos, con el fin de aliviar la carga de trabajo de 10s clientes y, a1 tiempo, centralizar
las reglas de negocio en un servidor, facilitando su mantenimiento.
Por esta raz6n, cada fabricante de DBMS ha creado su propio lenguaje que,
partiendo de la sintaxis y naturaleza de SQL, aiiade posibilidades como el trabajo
con variables, evaluacidn de expresiones condicionales y repetici6n de sentencias.
Dos de esos lenguajes, quiz2 10s m6s representativos, son Transact-SQL, conocido
originalmente como T-SQL y utilizado por Sybase y SQL Server, y PL / SQL, em-
pleado en Oracle.
Tanto Transact-SQL como PL / SQL son lenguajes lo suficientemente complejos
como para escribir varios libros especificos sobre ellos, puede encontrarlos en su
libreria habitual, por lo que en 10s puntos siguientes lo unico que se pretende es fa-
cilitar un acercamiento muy superficial a ellos.
Provenientes de una misma raiz, Sybase y SQL Server cuentan con un lenguaje
llamado Transact-SQL que, con el tiempo, ha evolucionado de manera distinta en
Prograrnacion de bases de datos con Visual Basic .NET
DECLARE @ I d e n t if icador T i p o
DECLARE P N u r n L i b r o s i n t
SELECT @ N u r n L i b r o s = 5
...
Las variables tambien pueden ser de 10s tipos VARCHAR, INTEGER y demhs
tipos indicados anteriormente como estandar en SQL.
- lgualdad
< Menor que
<= Menor o igual que
!< No menor que
> Mayor que
>= Mayor o igual que
!> No mayor que
<> Desigualdad
CS
mismo esquema del punto dedicado a Transact-SQL, prdcticamente con 10s mis-
mos ejemplos, per0 con la sintaxis de PL/SQL.
I d e n t i f i c a d o r Tipo;
DECLARE
NumLibros INTEGER;
BEGIN
N u r n L i b r o s := 5;
...
SELECT COUNT(1SBN) I N T O N u m L i b r o s
FROM L i b r o s ;
...
END:
Evaluacicin de exmesiones
En lugar de un valor constante, como en el ejemplo anterior, una variable pue-
de recibir el resultado de la evaluacih de una expresih. 6sta se compondria de
operandos, constantes y / o variables, y operadores aritmeticos y / o relacionales.
Los operadores aritmkticos son 10s habituales +, -, * y /, a 10s que habria que
afiadir el operador * * que efectua la potenciaci6n. Los aritmkticos =, <, <=, >, => y
! =. Los primeros son equivalentes a 10s indicados en la secci6n de Transact-SQL,
mientras que el ultimo comprueba la desigualdad entre dos operandos. Los opera-
dores 16gicos son AND, OR y NOT.
Utilizando estos operadores, la composici6n de expresiones se efectua de la
manera habitual y puede almacenarse el resultado, para un us0 posterior, o bien
emplearse directamente en un condicional o sentencia similar.
Si deseamos ejecutar una o varias sentencias dependiendo de que una cierta ex-
presi6n sea cierta o no, utilizaremos la sentencia I F/THEN/ELSE, prhcticamente
idkntica a la que existe en Visual Basic. La expresi6n a evaluar o condicional ir6
tras la palabra IF, mientras que las sentencias a ejecutar si dicha expresi6n es
cierta se pondrian tras la palabra THEN. Puede ser s610 una o multiples sentencias,
sin delimitar el bloque en forma alguna puesto que el final vendr6 marcado por un
E N D I F, un E L S E o bien un E L S I F en caso de que necesitemos evaluar expresiones
adicionales:
I F C o r l d i c i h n THEN
s e n tencia s ;
ELSIF C o n d i c i 6 n THEN
s e n t encia s ;
ELSE
sentencias;
END IF;
WHILE C o n d i c i h n LOOP
S e n t e n cia s ;
END LOOP;
La N y M del primer bucle se sustituirian por 10s valores extremos del bucle, por
ejemplo 1y 10, valores que irA tomando Contador mientras se ejecutan las senten-
cias que hay en el interior del bucle. En el segundo caso tan s610 tendria que susti-
tuir Condicion por la expresi6n condicional a evaluar en cada ciclo del bucle.
CREATF FUNCTION N u m T i t u l r r s (
r L I E d l t o r l a 1 I N I N T F (>EK D E F A U L T 0 )
RE? U R N NIJMBEK
N NUMBER;
BEGIN
I F I D E d i t o r i a l =- 0 THEN
S E L E C T C O U N ' I ' ( 1 S B N ) I N T O N FROM L i b r o s ;
ELSE
S E L E C T COUNT ( I S B N ) I N T O N FROM L , i b r o s
WHERE E d i t o r i a l = I D E d i t o r i a l ;
END I F ;
RETTJRN N ;
END;
Como ha podido ver en este capitulo, el lenguaje SQL, en general, y 10s deriva-
dos de cada RDBMS, en particular, suponen un extenso campo de estudio y aplica-
ci6n sobre el tratamiento de datos en sistemas como SQL Server u Oracle. Nuestro
objetivo era introducirle en ese campo, aunque apenas araiiando el mundo de po-
sibilidades existentes en el. Ha aprendido, no obstante, a utilizar sentencias DDL
para definir estructuras de datos bdsicas, como las tablas; DML para manipular
esos datos y DCL para otorgar y denegar privilegios a 10s usuarios.
Programacidn de bases de datos con V i s u a l Basic .NET
datos local cuando tanto la informaci6n como el middleware preciso para acceder a
41 se encuentran en el mismo ordenador, conjuntamente con la aplicacih. Es el ca-
so tipico en configuraciones monousuario, en el que el ordenador aloja programas y
datos e, incluso, no esta conectado a otros equipos en red.
En ocasiones, el acceso a esa informacih local puede efectuarse directamente
desde ADO.NET, sin necesidad de intermediario alguno. Es lo que ocurre, por
ejemplo, a1 trabajar con documentos XML tratindolos como si fuesen conjuntos de
datos. En otras, por el contrario, que la informaci6n este en el mismo equipo don-
de se ejecuta ADO.NET no implica que pueda manipularse sin mds, precisdndose
ese intermediario en forma de controlador. Un caso asi se encuentra a1 operar
sobre una base de datos Microsoft Access o dBase que est6 en el mismo ordenador.
Cuando el origen de datos es remoto, por ejemplo una base de datos alojada en
un servidor y gestionada por un RDBMS, siempre es preciso contar en el ordena-
dor donde se ejecuta la aplicacibn, el ordenador del usuario final, con un software
cliente dependiente del RDBMS que se emplee. ADO.NET, o el controlador que co-
rresponda, se comunicara con ese software cliente que, a su vez, se comunicar6
con el servidor a trav6s de la infraestructura de red correspondiente. L6gicamen-
te, es necesario tener instalado el software cliente del RDBMS y configurados 10s
parametros de comunicaci6n entre 61 y el servidor. Estos son aspectos que quedan
fuera del Bmbito de este capitulo, en el que se asume que utilizar6 las herramientas
indicadas desde el mismo ordenador en que esta instalado el servidor y se encuen-
tran 10s datos aunque, en la practica, las operaciones indicadas pudieran efectuar-
se t a m b i h remotamente.
Este producto, que forma parte de la suite Microsoft Office, es uno de 10s ges-
tores de bases de datos mas populares del mercado, especialmente en instalacio-
nes en las que el propio usuario opera sobre la informacibn, utilizando la interfaz
de esta aplicacibn, o bien utiliza una aplicaci6n desarrollada con VBA que se ejecu-
ta directamente dentro de Access.
Desde una aplicaci6n Visual Studio .NET podemos necesitar recuperar la infor-
macion que el usuario gestiona habitualmente utilizando Access 0,incluso, crear
una aplicaci6n que se encargue de actuar como interfaz para ese usuario a fin de
que no tenga que aprender a usar Access. En cualquier caso, en este apartado va-
mos a conocer algunos elementos de esta aplicacibn, 10s necesarios para crear una
base de datos y editar su contenido.
Comience por iniciar Microsoft Access, en este caso suponemos que la versi6n
es la 2000, se encontrard con un cuadro de diilogo similar a1 de la figura 3.1. Selec-
cione la opci6n Base de datos de Access en blanco y pulse el b o t h Aceptar.
Introduzca el camino y nombre de la base de datos a crear. La que va a descri-
birse a continuaci6n la encontrar6 en la carpeta Ejemplos del CD-ROM con el
nombre Libros .mdb.
Prograrnacidn de bases de datos con Visual Basic. .NET
I
I
I
I
Y I
. . . . - ~ - . ~ - . ~ . . - - " ~ ~ ~ - " ~ __
Dado el paso anterior, creando la base de datos, encontrarh una ventana similar
a la de la figura 3.2. En el margen izquierdo aparecen una serie de botones que dan
acceso a las distintas categorias de elementos que pueden existir en una base de
datos Access, mientras que a la derecha se enumeran las opciones que en ese mo-
mento hay disponibles en la categoria seleccionada.
Seleccione la opci6n Crear una tabla en vista DiseAo, la primera que aparece en
la lista de la secci6n Tablas, simplemente haciendo doble clic sobre ella. Apareceri
una nueva ventana, con una especie de cuadricula, en la que deber5 introducir el
nombre y tip0 de cada una de las columnas de la tabla que va a crearse. Comenzare-
mos con las columnas de la tabla Editoriales, como se aprecia en la figura 3.3.
Las columnas y sus atributos serin 10s siguientes:
0 IDEditorial: SerA el identificador de cada editorial. Seleccione el elemen-
to Autonumerico de la lista de tipos de datos y pulse el b o t h Clave principal
que hay en la parte superior. De esta forma la columna obtendri automiti-
camente un valor numeric0 incrementado para cada fila y que, ademis, ac-
tuari como clave primaria, generindose para ella un indice en el que no se
permitirin duplicados.
Nombre y Direccion: Dejaremos estas columnas con su tipo y atributos
por defecto, sirviendo para introducir el nombre y direcci6n de la editorial,
respectivamente.
lntroduccion de datos
El siguiente paso Idgico, una vez creadas las estructuras de la base de datos, es
ahora introducir alguna informaci6n en las tablas. Siempre partiendo del cuadro
3 . Origenes de datos
de diAlogo mostrado en la figura 3.2, haga doble clic sobre la tabla Editoriales,
o bien selecci6nela y pulse Intro, para abrir la cuadricula de introduccion de datos.
Figura 3.4. La relacion entre las dos tablas una vez establecida
Tab para ir avanzando de una columna a la siguiente y de una fila a otra. Introdu-
cidos 10s datos, cerramos la ventana para retornar a1 cuadro de didogo de tareas.
En este momento tenemos algunas editoriales en la tabla E d i t o r i a1e s, totalmen-
te imprescindible para trabajar con la tabla L i b r o s .
Aunque el objetivo que nos marcamos aqui no es otro que tener una base de da-
tos Access con alguna informacih ~ t i para
l utilizarla desde ADO.NET, creando
aplicaciones para el usuario, lo cierto es que para nosotros mismos no resulta de-
masiado c6modo tener que introducir el codigo de cada editorial de manera ma-
nual, escribiendo dicho c6digo que o tenemos que recordar o bien comprobar en la
tabla E d i t oriales.
Podemos simplificar esta operacion de forma muy simple. Seleccione la tabla
L i b r o s , en el cuadro de diiilogo de la figura 3.2, y pulse sobre el b o t h Diseiio,
abriendo asi de nuevo la ventana de disefio de la tabla. Seleccione la columna
E d i t o r i a l y, en la parte inferior, abra la p6gina Blisqueda. En ella encontrar6
opciones que permiten asignar a esta columna un control de busqueda. Seleccione
10s valores que se aprecian en la figura 3.8 para cada uno de 10s apartados. Opcio-
nalmente puede establecer el ancho de la columna y otros par6metros.
Ahora, a1 ir a introducir 10s datos de un libro, observarii que la columna E d i -
t o r i a l tiene asociada una lista desplegable. Puede escribir el c6digo de la edito-
rial 0,si lo prefiere, abrir dicha lista y elegirlo, como se hace en la figura 3.9. No cabe
duda de que resulta mucho miis c6modo, especialmente si son muchas las edito-
riales existentes y no resulta f6cil recordar el identificador de cada una de ellas.
lntroduzca algunos datos en las tablas para tener inforrnacion con la que traba-
jar en capitulos posteriores 0,si lo prefiere, tome la base de datos que se faciii-
ta en el CD-ROM, en la que existen algunas entradas.
Programacidn de bases de datos con Visual Basic .NET
Figura 3 lualmente
I
Puede solicitar una version de evaluacion de Microsoft SQL Server, valida du-
rante 120 dias, en http: //www.microsoft.com/spain/servidores/
sql/productinfo/evaluate. asp. Es una buena opcion si desea probar
este producto. En este ejemplo se utiliza la version 2000 del producto operando
sobre un sistema Windows XP Professional.
3 . Origenes de datos
Meta Data
Servioos de compabbibdad Serwes
Meta Data Serbicer
Haga clic con el b o t h secundario del rat6n sobre la carpeta Bases de datos y
elija Crear nueva base de datos. Se abrir6 la pigina Propiedades de la base de
datos, en la que debemos introducir el nombre interno de la base y 10s datos de 10s
archivos en 10s que se almacenar6 fisicamente. En la primera p6gina (figura 3.11) fa-
cilite el nombre de la base de datos, Libros,y deje el resto de opciones como est6n.
Las otras dos paginas del asistente se utilizan para configurar 10s archivos de tra-
bajo de la base de datos. Esta puede contar con uno o mas archivos para datos, que
se configuran en la p6gina Archivos de datos, y uno o mas archivos de registro de
transacciones, a configurar en la pigina Registro d e transacciones. Estos archivos
tienen un tamafio inicial, pueden crecer automaticamente y contar con un limite.
Dado que nuestra base de datos no va a contener una gran cantidad de infor-
macion, ni va a experimentar un volumen de transacciones importante, dejaremos
10s padmetros por defecto para ambos archivos. Puede, si lo desea, modificar el
camino y nombre de 10s archivos, como se ha hecho en la figura 3.12. En este caso
se ha aceptado el nombre por defecto, si bien se ha modificado el camino en el que
residirbn. En este momento la base de datos ya est6 creada y aparece en la carpeta
Bases de datos del servidor SQL Server. Hemos dado el primer paso.
-_I ---.-
A diferencia de lo que ocurri6 con Access, que justo tras la creacion de la base
de datos nos encontrabamos con un recipiente vacio, la base de datos SQL Server
r e c i h creada cuenta con una serie de tablas de sistema, diversas funciones y usua-
rios. Es decir, no estd vacia. Tendremos, no obstante, que definir las estructuras de
datos que necesitamos, comenzando por las tablas donde se alojara la informa-
ci6n. El proceso es similar a1 descrito previamente para Access dado que la interfaz
de usuario es parecida. Abra la carpeta Bases de datos y tambien la base de datos
Libros. Haga clic con el boton secundario del rat6n sobre el elemento Tablas y se-
leccione la opci6n Nueva tabla.
Figura 3.12. Opciones de 10s archivos de datos
En este momento tenemos definidos todos 10s atributos de la tabla Libros, tal
y como se aprecia en la figura 3.14, per0 no cierre aun la ventana.
a4
II
Figura 3.16. lntroducimos 10s datos de vartas editoriales
De manera an6loga puede introducir 10s datos de algunos libros, teniendo en
cuenta que el c6digo de editorial deberd ser uno de 10s previamente definidos en la
tabla E d i t o r i a1e s . Como ocurria con Access, de introducirse un c6digo inexisten-
te obtendremos un mensaje de error (vkase figura 3.17) y la operaci6n de inserci6n
no se Ilevard a cabo.
MOF de la b a r de datosque r va a a M a
Cap-03 bbms-Data MDF
s PBDDUsualBasicNET~~mplos
I 1-
vista
Como se apuntaba anteriormente, SQL Server es un RDBMS con todas las posi-
bilidades que tienen estas aplicaciones, posibilidades algunas inexistentes en Mi-
crosoft Access. Una de esas posibilidades es la definici6n de vistas, objetos que se
almacenan en la base de datos y ejecutan a demanda de las aplicaciones cuando 6s-
tas las abren como si se tratasen de tablas. El us0 de las vistas ahorra a las aplica-
ciones y usuarios la composici6n de consultas mds o menos complejas para poder
obtener 10s datos que necesitan.
Vamos a definir una vista que, aunque simple, nos serviri para conocer 10s pa-
sos que habriamos de dar en cualquier caso. Dicha vista devolverd las editoriales y
10s titulos que les corresponden, estableciendo una relaci6n entre ambas tablas.
Los pasos a dar son 10s indicados a continuacih:
1. Haga clic con el b o t h secundario del rat6n sobre la carpeta Vistas de la base
de datos y luego seleccione del menu emergente la opci6n Nueva vista. Apa-
receri una ventana con varias secciones, como la de la figura 3.19, inicialmen-
te vacias.
- - - _ _ _ _ ~-
-
r 1 - 7
*
- L
-
gib- i;r12
1'1
I>
*
1,
3. Haga clic con el boton principal del rat6n sobre las casillas que aparecen a la
izquierda de las columnas Nombre, en la tabla E d i t o r i a l e s , y T i t u l o y
P r e c i o , en la tabla L i b r o s . De esta manera las selecciona como columnas
para el resultado final. Observe c6mo esas columnas aparecen en el panel
que hay debajo del diagrama y t a m b i h en la consulta SQL.
4. Utilice el panel que aparece debajo del diagrama para establecer criterios de
busqueda u ordenacion. Puede, por ejemplo, desplegar la lista de la colum-
na Orden asociada a la P r e c i o para que 10s datos se ordenen ascendente-
mente por el precio, es decir, de m6s baratos a m6s caros. T a m b i h puede
introducir condiciones de busqueda, por ejemplo que el precio est6 en un
cierto rango.
5. Pulse el b o t h Ejecutar, identificado con un signo de admiracion, para pro-
bar la vista y obtener, en la parte inferior, el resultado, como se ve en la figu-
ra 3.21. Puede modificar 10s criterios y el orden segun le interese. En la base
de datos de ejemplo no existen criterios y el orden es el obtenido por defecto.
Programacidn de bases de datos con Visual Basic .NET
>
BEWEEN 10,75AND 40
n S
Hasta ahora, todos 10s elementos creados en la base de datos SQL Server han si-
do generados mediante asistentes que se han encargado de producir las sentencias
SQL adecuadas, enviindolas a1 servidor para su ejecuci6n.
A1 crear un procedimiento almacenado, sin embargo, no tendremos m i s reme-
dio que escribir el cbdigo, ya que un procedimiento almacenado es, en si, un blo-
que de c6digo con un nombre.
3 . Origenes de datos
T ~ O
REATE PROCEDURE NurnTtdulos
OEdtonal INTEGER '-1 IL_
It I
- --
1.11/11
................ ............ .........
.i
" "
i...............
" -alairt&
G R O U P BY E.Nombre
END
2 Apress
3 HcGraw-Bill 1
Oracle siempre ha tenido fama de ser un producto robusto, fiable y muy escala-
ble, per0 no precisamente ficil de instalar o administrar. Esto, por suerte, va cam-
biando en las tiltimas versiones del producto, como la 8i y 9i. Puede obtenerse el
RDBMSdeOracledesdehttp: / / o t n . o r a c l e . c o m / s o f t w a r e / c o n t e n t . h t m l ,
en distintas versiones y ediciones. Tan s6lo tiene que registrarse en OTN, es gra-
tuito, proceder a la descarga e instalaci6n siguiendo 10s pasos indicados.
En 10s puntos siguientes va a utilizarse Oracle8i Release 3 (versi6n 8.1.7) sobre
un servidor Windows .NET Enterprise Server, asumiendo que el directorio raiz de
Oracle es OraHome81. Si en su sistema es uno distinto t6ngalo en cuenta por 10s
cambios que pudieran ser necesarios.
I I
IC S
Una vez tenemos la base de datos creada y en marcha, el siguiente paso serfi la
definici6n de las tablas que la formarh. Abra la carpeta Oracle - OraHome8l de
nuevo de la lista de programas y seleccione la opci6n Database AdministratiowDBA
Prograrnacidn de bases de d a f o s con Visual Basic .NET
Studio para iniciar el Oracle DBA Studio. En el cuadro de di6logo que aparece,
preguntando si desea iniciarlo en mod0 est6ndar o conectando con un servidor de
administracidn, deje seleccionada la primera opcidn y pulse Intro. Transcurrido
un momento, deberia encontrarse con una interfaz como la de la figura 3.29. En el
panel izquierdo aparecen las bases de datos disponibles, conteniendo en su inte-
rior objetos tales como esquemas, tablas, procedimientos, etc.
Como ver6, en el Brbol que hay en el panel izquierdo no aparece nuestra base
de datos, la que hemos creado en el punto anterior, por lo que tendremos que afia-
dirla. Seleccione la opcidn File>Add Database to Tree. Aparecer6 un cuadro de dig-
logo con dos opciones: afiadir una base de datos manualmente, facilitando sus
datos, o bien seleccionar una de las que aparecen en el archivo tnsnames ora de .
Oracle. Seleccione esta segunda opcidn y marque la base de datos Libros,hacien-
do clic a continuacidn sobre el b o t h OK. En ese momento la base de datos apare-
cer6 como un nuevo nodo del Brbol.
Haga clic sobre la base de datos para desplegar su contenido, iniciando sesi6n
como administrador de la base de datos (SYSDBA) utilizando la cuenta SYSTEM.
Despliegue la rama Schema y, dentro de ella, elija el nodo Table. Haga clic sobre
3. Origenes de datos
61 con el b o t h secundario del rat6n y elija la opci6n Create Using Wizard para po-
ner en marcha el asistente de creaci6n de tablas.
I
DBA Studio combines multiple
database tools in one application
Use DBA Studio to administer
b Instances.including startup.
shutdown, and initialization
I Schemas. including tables.
indexes. and Oracle8 objects
I SecurIly,including user
accounts, roles, and privileges
I Storage. including tablespaces,
datafiles, and rollback segments
I Replication.including
rnultimaster and snapshot
replication
I OracleBlJVM (JServer). including
namespaces. CORBA and EJB
components and their
permissions
Aunque para este ejemplo, y por inmediatez, vamos a usar la cuenta SYSTEM
para conectar con la base de datos, lo habitual es que se creen 10s usuarios que
van a tener acceso a ella y se utilice una de esas cuentas para operar.
la lista Wich Schema do you want the table to be part of? y elegir cualquiera
de las creadas como ejemplo en la base de datos, por ejemplo el conocido es-
quema SCOTT.
2. El segundo paso consiste en la definici6n de las columnas que tendri la ta-
bla. A la izquierda aparece una lista, inicialmente vacia, con las columnas,
mientras que a la derecha se reflejan 10s atributos de la columna elegida en
cada momento. Introduzca 10s datos de las columnas siguientes, pulsando el
b o t h Add para ir aiiadihdolas a la lista.
0 IDEDITORIAL: Asignele el tip0 NUMBER estableciendo 32 como tamafio.
En Oracle no hay un tip0 similar a1 autoincrementado de SQL Server y
Microsoft Access, aunque podria conseguir el mismo efecto por medio de
un desencadenador y una secuencia.
0 NOMBRE y DIRECCION: Selecci6n el tip0 VARCHAR2 introduciendo 50 en
el apartado Size.
I Columns defined
Columns Definftion
Pmpetttesof col
Column Name
Column Datatype
size
I1 Scale
A Does this column have a defaultvalue7If so, please enter
.xJ
Add 1 Remwe)
- - __
Cancelar J, Awda
- ) 4 @tarlor Siguiente 9 Termlnar 1
Name UBROS
Schema SCOl?
S
'I
Foreign Constraint
constraints on column EDITORW -
Column Name EDiTORlM
Column Dataiype NUMBER(3Z)
@ Yes,me column is 8
Summaw
Name LIBROS
Schema SCOTT
SQL generated
_ _ I -.__-l__ll_.l_____lll__
ll__..l__ __.~ l _ _ l _ _ ^ _ ~ _ _ l ~
I t'
I I:
lDEDllORlAL
i__._
__I_-
# NORIBRE
Anaya Multimedia
McGraw-Hill
_ _ .DlRECClON
.. - .-.
Juan lgnacio Luca de Tena, 1 5
EdiRcio Valrealty, l'planta
ci ~-
_I ~ ~ _ - ^ I ( ~ - ~ - I ~-~
~ - - --
Como hicikramos en la base de datos SQL Server, vamos a definir una vista
simple que nos permita obtener una lista de todas las editoriales junto con 10s titu-
10s que le corresponden. Seleccione la carpeta View, en el panel izquierdo del Ora-
cle DBA Studio, y seleccione la opci6n Create Using Wizard. En este caso el asistente
se compone de 10s siguientes cinco pasos:
1. En la primera ventana introduzca el nombre de la vista que vamos a crear,
LIBROSEDITORIAL, y seleccione el esquema SCOTT para alojarla. Pulse el
b o t h Siguiente.
2. La segunda ventana mostrarA en el panel izquierdo una lista de las tablas
disponibles, junto con sus columnas, a fin de que seleccionemos aquellas que
deseamos incluir en la vista. En la figura 3.37 puede ver c6mo se ha incluido
3 . Origenes de datos
-
I
Summary
Name LIBROSPOREDITORIAL
Schema SCOTT
r ModifyView Definition
This wll override the view deflnltion specifled in the prevlous pages Of
the wizard
--i
_ l
_ __
,
j \VHERE (SCOTT EDITOPIALES IDEDITORIAL= SCOTTLIBROS E
WTH RE4D ONLY
__
Can ce Ia r
I_
Ayuda
__ -
, - Anterior
-
I 1 a (r)
Figura 3.38. Resurnen de la creacion de la vista
Localice la carpeta Functions y haga clic sobre ella con el b o t h secundario del
ratbn, seleccionando la opci6n Create. Apareceri un cuadro de didogo en el que
tiene que dar tres pasos:
3 . Origenes de datos
N NIIXEEF,
BEGIA
I F IDEdltOrlaI = 0 THEN
*ELECT COUNT(1SBN) I N T U N FFnM Llbros:
EL E
ELECT COUNT(1SBN) IITTIJ N GO21 Llbros
IUHERE EdlcOr1al = IDEditonal:
ElII I F :
FETLIPIJ N:
Observe c6mo se indica que existe un pardmetro de salida, cuyo tip0 es el defi-
nido previamente en el paquete LIBROSPKG.Fijese tambidn en c6mo se inserta el re-
sultado de la consulta SQL en la variable Resultado me.diante la sentencia OPEN.
A1 cerrar la ventana habr6 finalizado la creaci6n del procedimiento almacenado
que, en el punto siguiente, ver5 c6mo utilizar.
3 . Origenes de datos
-
~ _ _ _ _ _ _ _ ~ ^ _ ~ . - I I _ _ - ~
---I_I_
Inter Base
Oracle es un RDBMS disponible en multiples sistemas operativos, segun se
apuntaba anteriormente, per0 no por ello ser5 siempre el product0 mhs adecuado,
3 . Origenes d e datos
IBCorrsole
onsole Yiew sewn Database Iools - Help
ctwn Desciiption
Login Login to the relected sewer
Register Register a new InteiBase Server
Un Register Unregirter an InterBase Server
Diagnose Conn Diagnose a connection to a serve1
Pioperties Mew Server properties
Add Certificate Add a license certificate
I, --
Server Local Serve~
Fle(sL
En este momento ya tenemos a nuestra disposici6n una base de datos vacia, por
lo que podemos proceder con la definici6n de las tablas.
I
- @
- *
InterBaaeServers
- eD
LocalSe,ve,
gl
p ;
tction
Disconnect
Properties
Dcrcrrplion
Disconnect fmm Ihe curient database
Show database propeilie~
DatabaseStalirtcs Display databare statistics
Domainr Shutdown Shutdown the database
Tables Sweep Perloim a database sweep
Indexer
Tiansaction Reco Recover limbo tiansadions
4 Views View Metadata View Database Metadata
& Shied Procedures
Dalabare Restart Restart a database
fx External F u n c l i ~ r
Drop Database Drop the curtent database
% Generators
Databare Backup Backup an InterBafe dalabare
@ Exceptions
Connected Users V w a 1st of useif cuirently connected to the server
d Blob Filters
3 Roles Rertore Databare Hertoce an InterBare database
Backup
a9 Cert,laater
seiver Log
& Urm
+ % dimension
I D L i b r o I N T E t i E R NOT NTJLL P R I M A R Y K E Y ,
I S B N CHAR(13) NOT NULL U N I Q U E ,
T i t u l o VARCHAR(501,
Autor VARCHAR(50),
Editorial I N T E G E R ,
3 . Origenes de datos
Precio DECIMAL ( 6 , 2 ) ,
FOREIGN K E Y (Editorial) R E F E R E N C E S
Editoriales(IDEditoria1)
I
hentrkakd3 AutoMy'oN
Tras ejecutar las dos sentencias puede cerrar la ventana de Interactive SQL. Ve-
ra que las tablas aparecen en la carpeta Tables de IBConsole. Abriendo su menti
emergente podri efectuar diversas tareas, como extraer el c6digo DDL o acceder a
su ventana de propiedades.
dades, y luego seleccione la pdgina Data. En ella puede, como se aprecia en la figu-
ra 3.48, introducir 10s datos de las editoriales, sin olvidar asignar a cada una de
ellas un c6digo cinico.
IDependenclesI
i
1 I
Piopeillas Meladala Peirnisslons Data
P
3 Apress 901 Grayson Stieet
. b i + - r C Comnt h Relresh
Figura 3.48. Desde IBConsole podemos acceder al contenido de las tablas y editarlo
l L ’ I
~ _ I _ _I
A1 igual que para definir las tablas, tendremos que recurrir a la herramienta In-
teractive SQL para crear la vista L i b r o s E d i t o r i a l . Introduzca el c6digo siguien-
te y pulse el b o t h de ejecuci6n.
SET TERM ; #
La primera sentencia cambia el carficter de fin ; por #, de tal forma que cuando
Interactive SQL encuentre el ; que hay tras el primer S E L E C T no crea que el proce-
dimiento almacenado finaliza ahi. La ultima sentencia devuelve este parsmetro a
su estado por defecto.
Observe que tras la ejecuci6n de un S E L E C T u otro, dependiendo del valor de
C o d E d i t o r i a l , se usa una sentencia llamada SUSPEND. Esta hace posible la devo-
luci6n del resultado desde el procedimiento almacenado a1 c6digo que lo invoque.
El segundo procedimiento almacenado, N u m T i t u l o s E d i t o r i a l , se crearia de
forma muy similar. En este caso se declaran como valores de retorno tantas varia-
bles como columnas sigan a la clfiusula SELECT, introduciendo 10s valores extrai-
dos en ellas mediante INTO.
SET TERM # ;
CREATE PROCEDURE NumTitulosEditorial
RETURNS (Nombre VARCHARISO), NumTitulos INTEGER)
AS
BEGIN
FOR SELECT E.Nombre, COUNT(L.Titulo)
FROM Editoriales E, Libros L
WHERE E.IDEditoria1 = L.Editoria1
GROUP BY E.Nornbre
INTO :Nornbre, :NumTitulos
DO SUSPEND;
3. Origenes de datos
END#
SEI’ TERM ; #
Nota
Con el objetivo de preparar este nuevo libro para introducir 10s datos que nos
interesan, similares a 10s escritos en las bases de datos de ejemplo, vamos a hacer
algunos cambios en su estructura. Los pasos, muy sencillos, son 10s que se descri-
ben a continuacion:
3 . Origenes de datos
4
5
67 1
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
- ___
?m,
Hop1 ,( mJa7 ZFOjz 7
.Isto
Completados estos pasos, tenemos un libro Excel con una estructura similar a
las tablas creadas previamente en Oracle o Access. Como habra observado, no he-
mos indicado en punto alguno el tip0 de 10s datos, las relaciones, claves, etc. Excel
no es un RDBMS y la mayoria de estos aspectos no se contemplan. El tip0 de cada
una de las columnas, por ejemplo, sera deducido por ADO.NET a partir del conte-
nido que tengan las celdillas.
6
7
Figura 3.53. El libro Excel tras introducir 10s titulos de las columnas correspondientes
a la hoja Editoriales
Intr
Microsoft Excel es una aplicacidn para usuario final y, por ello, la introduccih
de datos resulta muy sencilla, a1 contar con caracteristicas como el autocompletado,
la creacidn automatics de secuencias, etc. h t e , sin embargo, no es un libro sobre
Excel, por lo cual obviaremos toda esa funcionalidad y nos limitaremos a introdu-
cir 10s datos, sin mds.
En el punto anterior, a1 escribir 10s titulos de las columnas, ya hemos introduci-
do varios datos en cada una de las hojas del libro, aunque esos datos fuesen 10s ti-
tulos o nombres de las propias columnas.
Usando exactamente el mismo m4todo escribiriamos la informacih de cada fi-
la, no tenemos mds que utilizar las teclas del cursor para situarnos en la celdilla
3 . Origenes de datos
adecuada en cada caso. En la figura 3.54 puede ver el aspect0 de la hoja Libros tras
introducir una serie de datos.
C D E F :
1 IDLibro ISBN Tilulo Autor Editorial Precio -
2 1 1 853115 94 1 User Interface Design for Programmers Joel Spolsky 3 31
3 2 84415 1136 5 SQL Server 2000 Francisco Charte 1 1075
4 3 84415 13243 Guia practica para usuarios JBuilder 7 Francisco Charte 1 1075
5 4 84415 1392 9 Programaclon con Visual C# NET Francisco Charte 1 35
6 5 84415 1376 7 Programacion con Visual Studio IlET Francisco CharteiJorge Serrano 1 40
7 6 84415 1351 1 Programacion con Visual Rasic NET Francisco Charte 1 39
8 7 81415 1290 6 Guia practica para usuarios de Visual Basic NET Francisco Charte 1 10 75
9 8 81 415 12914 Guia practica para usuarios de Visual Studio PIET Francisco Charte 1 10 52
10 9 84415 1261 2 Programacion con Delphi 6 Kvlix Francisco Charte 1 37 26
11 10 84 415 1255 8 Guia practlca para usuarios de Delphi 6 Francisco Charte 1 10 52
12 11 84415 1230 2 Manual a*,anzado Excel 2002 Francisco Charte 1 21 04
13 12 84415 1202 7 Guia practica para usuarios de Excel 2002 Francisco ChattelM Jesus Luque 1 10 52
14 13 84 415 1132 2 Guia practica para usuarios de Kylix Francisco Charte 1 1052
15 14 81415 11454 lntroduccion a la programacion Francisco Charte 1 24 04
16 15 84 7615 234 5 Manual del microprocesador 80386 Chris H Pappas&William H Murray Ill 2 40
17 n
_ I _ _ _ I
_I
___ ~ _ _ _ _ - ~
_ _~~ - .-_-^ _
_~ ~__ _ _ - -
____ - - -__
I
cualquier punto del Brea central. AparecerB un recuadro con dos columnas. Intro-
duzca en la parte superior el nombre que va a darle a1 nuevo tipo, en este caso
Editorial.A continuaci6n vaya introduciendo, en la columna izquierda, el nombre
de cada columna de datos, indicando a la derecha su tipo. En el detalle de la figu-
ra 3.56 puede ver c6mo se han definido las tres columnas necesarias para registrar
las editoriales.
I/ Categorias: Plantillas:
I - - ___
Arc%wo para crearun esquemi para documento; XML
Cuadro de herraKeEtas B K
IwuemaXML - -_-A
4 Punter0
element
attribute
attributeGroup
a compbxType
simpleType
EZ group
El any
anyAttrlbute
facet
I IDEditorial integer
D clave
, Nombre string
I
.
Guarde el documento L i b r o s xsd, esquema que, alojado en un archivo inde-
pendiente, serviri para establecer la estructura de 10s documentos XML que ac-
tuarian como bases de datos, contando siempre con un elemento de primer nivel
L i b r o s que contendria a E d i t o r i a l e s y L i b r o s .
3 . Origenes d e datos
Irchivo Edtcion ter Proyecto Generar pepurar Ezquema nerramientas VeEtana Ayuda
J--l-G X Q . @* t Debug
q%.
Jadro de herramtentas 4 X Libros.xrd* I
,quema XML
4 Funtem Libros (Libros)
b
1
E element Edtoriales Editorial
A attribute Libror Libra
Casesensitive (Fredetermmado)
#
attributeGroup IsDataSet (Predetermmado) $
E+ complexType Locale (Fredetermmado)
3
% 5lmpleType I
abstract (Predetermmado)
G group
block (Fredetermmado)
0 any
COrnplexType 4 x 5 COmpleXType >
)a, anyAttribute Edtoriales Editorial Libros Libro default
F facet final (Predetermmado)
D clave fixed
& Relation form (Predetermmado)
id
key (Colecclo")
name Libros
nillable (Fredetetmmado)
rubsttutionGrat
type (Libros)
Figura 3.57. Aspect0 visual del esquema XML en el entorno de Visual Studio .NET
Nota
- --- "-- -
-_________
___x - - -__^( I X I - ____ ---___.-ll-__X -____I_- I I
inferior el nombre del archivo, por ejemplo L i b r o s . xml. A1 pulsar Abrir se en-
contrarii en el editor de Visual Studio .NET con un documento compuesto de una
sola linea:
Ya tenemos la marca <Libras> que actua como raiz de todo, como si fuese el
inicio de la base de datos, asi como la marca de cierre </Libras>.
Aunque podriamos ir introduciendo 10s datos manualmente, el editor de Vi-
sual Studio .NET se encarga de ir introduciendo de forma automitica las etiquetas
de cierre y, ademis, ofrece listas de posibles etiquetas y parimetros, es mucho
m i s ficil pulsar el b o t h Datos que aparece en la parte inferior del editor. A1 ha-
cerlo nos encontramos con una interfaz como la de la figura 3.58, en la que pode-
mos introducir 10s datos como si de una tabla de una base de datos se tratase. En el
margen izquierdo seleccionamos el elemento a editar, mientras que a la derecha
vamos afiadiendo las filas de datos.
A medida que vamos editando visualmente 10s datos de cada editorial y libro,
Visual Studio .NET se encarga de actualizar el documento XML para que siempre
est6 sincronizado. Tambi6n podemos editar directamente el documento, viendo
posteriormente 10s datos en forma de tabla. Lo interesante es que la informacih,
el documento L i b r o s . xml que puede ver completo a continuacih, es compatible
con todos 10s sistemas operativos, plataformas hardware y Ienguajes de progra-
maci6n. Es, por tanto, el recurso ideal para el intercambio de informacih.
&rchvo EdKi6n \Ler Froyecto senex pepwar XML He%rarmentas Ventana Aygda
j LlbrOS.nml* I 1 1 x
rio
En la mayoria de empresas actuales, especialmente de un tamaiio medio a gran-
de, existen redes heterogheas, diferentes sistemas y todo ello distribuido geogrd-
ficamente en distintas localizaciones que, incluso, se encuentran en distintos paises.
Gestionar 10s recursos de la infraestructura informdtica de este tip0 de empresas
supone un desafio para 10s administradores y, en ocasiones, tambien para 10s de-
sarrolladores de aplicaciones.
Las redes se componen de ordenadores, dispositivos independientes o asocia-
dos a un ordenador, tales como impresoras o medios de almacenamiento, grupos o
perfiles, cuentas de usuario, etc. Generalmente cada sistema cuenta con un servi-
cio de directorio propio que facilita la administracion de estos recursos, como el
servicio de directorio de Windows NT o el de Novel1 Netware. Existe un protoco-
lo, bastante aceptado, para acceder a estos servicios de directorio llamado LDAP.
Con el objetivo de simplificar la gestion de recursos en distintos tipos de direc-
torio, Microsoft incluy6 en Windows 2000 Server el Directorio activo (DA para
abreviar) o Active Directory. Mediante DA es posible acceder a recursos de cual-
quier punto de la red, sin importar el servicio de directorio subyacente del sistema
con que funcionen las mdquinas. Gracias a DA, 10s administradores pueden orga-
nizar la informacih de forma mucho mAs coherente y organizada, simplificando
la localizaci6n de 10s recursos y su gesti6n remota.
La information se almacena en el DA con estructura jergrquica, en lugar de re-
lacional al estilo que hemos conocido en 10s puntos previos. En la posicih m6s al-
ta se encuentran 10s bosques, formados For drboles jerdrquicos de dominios que, a
su vez, alojan unidades organizativas. Estas contienen mdquinas, usuarios y otros
elementos.
Por su complejidad, queda fuera del ambito de este capitulo entrar en 10s deta-
lles sobre el funcionamiento y 10s esquemas del DA. Puede encontrar mas in-
formation sobre este servicio en h t t p : / / M S D N . M i c r o s o f t . e s .
dS d v s l t a Avvda
Builtin
0Computers
lc3J Domain Controllerr
0 Users
i- &J EarySoft
Administracion
Demono
I 1 I II
77
Figura 3.59. Herramienta de administracion del Directorio activo
Resumen
A lo largo de este capitulo ha creado msltiples bases de datos y documentos,
recursos que nos servirin como origenes de datos para 10s ejemplos a desarrollar
en capitulos posteriores. Por el camino, y aunque muy vagamente, tambien habr6
adquirido cierta familiaridad con algunos de 10s productos, RDBMS y no RDBMS,
Prograrnacidn de bases de datos con Visual Basic .NET
que van a usarse como servidores o productores iniciales de 10s datos. Ha aprendi-
do a definir estructuras de tablas en distintas bases de datos, codificar procedimien-
tos almacenados en 10s lenguajes de varias de ellas, crear vistas y ejecutar algunos
de esos elementos para obtener unos resultados visibles de manera inmediata.
El objetivo principal, mAs a116 de esa familiarizacion con SQL Server, Oracle o
Excel, ha sido definir la estructura e introducir 10s datos que, tal y como se ha co-
mentado, nos servirdn de base para 10s siguientes capitulos. Antes, no obstante,
deberemos conocer tambikn otros elementos, como la estructura de ADO.NET y
sus componentes principales. A ello est6n dedicados 10s dos capitulos que encontra-
r6 a continuacion de 4ste.
Con la denominacion generica ADO.NET se hace referencia a todos 10s servi-
cios de acceso a datos disponibles en la plataforma Microsoft .NET, servicios que
podemos usar desde cualquiera de 10s lenguajes de programacion capaces de pro-
ducir c6digo MSIL, entre ellos Visual Basic.
Los elementos de ADO.NET est6n pensados para simplificar el acceso a datos,
sin perder por ello flexibilidad y eficacia. Sus componentes se encuentran reparti-
dos por varios imbitos con nombre que, en su mayor parte, tendr6 ocasion de co-
nocer en el proximo capitulo.
Nuestro objetivo, en este capitulo, es obtener una vision general de ADO.NET
desde un punto de vista bastante teorico, obteniendo 10s conocimientos necesarios
para que, a medida que conozcamos estos servicios en 10s siguientes capitulos, com-
prendamos ficilmente su funcionamiento y raz6n de ser. Desde este nivel, relati-
vamente alto, ser6 m6s sencillo percibir la arquitectura de ADO.NET.
Microsoft cuenta desde hace aiios con un mecanismo de acceso a datos, ADO,
muy asentado en el sector, disponible en la pr5ctica totalidad de las versiones de
Windows y usado por casi todas las herramientas de desarr,ollo disponibles. ADO,
gracias a la existencia de diversos controladores OLE DB, ofrece acceso a origenes
de datos de todo tip0 y facilita a1 desarrollador las operaciones m6s habituales.
4. Introduccidn a ADO.NET
Para proponer un nuevo modelo de acceso a datos, en este caso ADO.NET, era
precis0 alcanzar unos objetivos que le hiciesen superior a ADO y, por tanto, el
cambio evolutivo de uno a otro, por parte de 10s desarrolladores, mereciese la pe-
na. Dichos objetivos se han llegado a alcanzar y podrian resumirse en 10s siguien-
tes puntos:
i6 rn
Aunque ADO.NET cuenta con un mecanismo para lectura directa de datos des-
de el servidor a1 cliente, utilizando una conexi6n unidireccional y s610 de lectura
especialmente apropiada para la elaboraci6n de informes y tareas similares, lo miis
habitual sera trabajar con conjuntos de datos en el cliente.
Los pasos para obtener un conjunto de datos o Data S e t son, por regla general,
10s siguientes:
1. Se establece una conexi6n con el origen de datos.
2. Ejecuci6n de un comando que recupera informaci6n de dicho origen.
3 . Creaci6n en memoria del conjunto de datos.
4. Cierre de la conexi6n.
:
vuelve al rimero, tenemos un conjunto de datos ADO.NET alojado en un corn-
ponente. ste se comunica mediante protocolos estiindar con diferentes tipos de
clientes, entregando el conjunto de datos en formato XML. El primer cliente, el
que estii m i s a la izquierda, podria ser una aplicaci6n Windows tipica, el segundo
un cliente web sobre cualquier sistema y el tercero una aplicaci6n escrita, por ejem-
plo, con Borland Kylix funcionando en Linux.
4. lntvoduccidn a ADO.NET
Servidor de
aplicaciones
t I
XML
I Internet/lntranet
Figura 4.1. La transferencia de 10s conjuntos de datos en formato XML abre las puertas
a la interoperabilidad con clientes heterogeneos
-- ~ ___--- _~ - _-- - --
A pesar de lo dicho, aun queda en ADO.NET un vestigio del ~ S de O cursores:
10s lectores de datos o DataReader. Estos se usan para ejecutar s610 sentencias de
consulta, obtenigndose un cursor ligero que s610 permite la lectura y, ademas, es
unidireccional, facilitando tan s610 el avance de una fila a la siguiente hasta llegar
a1 final.
Los lectores de datos son utiles en casos en 10s que va a recuperarse un conjun-
to de datos con el objetivo de preparar un informe, realizar unos cilculos o tareas
similares, de tal forma que, aunque se mantenga la conexi6n abierta con el servi-
dor, el proceso dure el menor tiempo posible.
La existencia de estos lectores de datos hace posible la recuperaci6n de infor-
maci6n sin necesidad de transferir todo el conjunto de datos completo desde el
servidor a1 cliente en un solo paso, reduciendo asi el us0 de memoria en el cliente,
que no tiene necesidad de almacenar todos 10s datos a1 poder procesarlos fila a fi-
la. En el octavo capitulo conocera 10s componentes DataReader y aprenderii a
utilizarlos en aplicaciones propias.
Los servicios de ADO.NET dan cabida a las necesidades de todo tip0 de aplica-
ciones, desde las mas sencillas de tip0 monousuario hasta aquellas que deben ope-
rar con conexi6n esporadica a1 servidor. Esto demuestra la flexibilidad y versatilidad
de ADO.NET respecto a otros mecanismos de acceso a datos, mucho mas limita-
dos en cuanto a posibilidades se refiere.
Las distintas combinaciones de componentes ADO.NET, proveedores y contro-
ladores dan como resultado diferentes soluciones que pueden aplicarse a multi-
ples escenarios, entre 10s cuales se encontrarian las siguientes configuraciones:
dor del cliente y 10s elementos que hay en su interior 10s diversos compo-
nentes. La aplicacih utilizaria un conjunto de datos ADO.NET que podria
guardar directamente, en formato XML, o bien emplear una base de datos
de escritorio o un documento Excel como deposit0 de la informacih. La pri-
mera opci6n es la mas eficiente y simple, ya que no se precisa ninguna otra
aplicacih externa como seria Excel, mientras que la segunda habilitaria la
posibilidad de tratar la informaci6n desde fuera de la aplicacion cliente, con
un product0 estandar.
I------- t t I
Ya, 1
0 1
Configuracion cliente/servidor
Figura 4.3. Esquerna de una configuracion cliente/servidor tipica
V 1
v)
0
c
m
U
configuracion cliente/servidor
con conexion esporadica
Figura 4.4. La configuracion con conexion esporadica es similar a la cliente/servidor
4. Introduccidn a ADO.NET
Configuracion distribuida
Figura 4.5. Configuracion de una aplicacion distribuida en tres capas
Este breve capitulo nos ha servido para obtener, de una manera tebrica, una
idea general sobre las posibilidades y funcionalidad del modelo de acceso a datos
ADO.NET, un modelo compuesto por interfaces y componentes que, en su mayor
parte, va a conocer en el pr6ximo capitulo. Ahora ya sabe que ADO.NET no utiliza
cursores ni conexiones continuas con el servidor para efectuar su trabajo, que 10s
conjuntos de datos se transfieren y almacenan en formato XML y que es posible
utilizar ADO.NET en cualquier configurac%n, desde la mas sencilla hasta la m i s
compleja.
A partir del sexto capitulo, tras conocer en el quinto 10s Ambitos, interfaces y
clases m6s importantes de ADO.NET, comenzar6 a usar todos esos elementos para
conectar con un origen de datos y ejecutar diversos comandos. Todos 10s ejemplos
se basan en el us0 direct0 de ADO.NET, sin ayuda de 10s asistentes, disefiadores y
elementos de Visual Studio .NET. Una vez conozca perfectamente c6mo funciona
y c6mo utilizar ADO.NET, pasaremos, en la tercera parte, a estudiar c6mo Visual
Studio .NET puede ahorrarnos una parte importante del trabajo.
Aunque mantenihdonos aun en el campo te6rico iniciado en el capitulo pre-
vio, en 6ste vamos a ir conociendo 10s Bmbitos con nombre que componen ADO.NET
y las interfaces y clases que podemos encontrar en ellos, informacion fundamental
para, en 10s capitulos siguientes, ir utiliz6ndolos para conectar con un origen de
datos, recuperar informacih, ejecutar comandos, etc.
Recuerde que en la ayuda electrhica de Visual Studio .NET existe una referen-
cia de toda la biblioteca de clases .NET, en la que encontrara la lista de elementos
relacionados con ADO.NET.
Nuestro objetivo, en este capitulo, es introducir 10s elementos de mayor inter&
y esbozar un esquema general del modelo de objetos ADO.NET, per0 recuerde que
todos 10s detalles sobre Bmbitos, clases y sus miembros se encuentran en la infor-
maci6n de referencia de Visual Studio .NET.
Para poder utilizar estos dos ~ltirnos,en caso de que 10s necesite, tendra que
aAadir una referencia en la carpeta Referencias del proyecto al ensamblado
correspondiente. En un capitulo posterior se indicara de donde puede obtener
estos controladores y como instalarlos y usarlos.
roveedores
Como se comentaba anteriormente, ADO.NET es un mecanismo de acceso a da-
tos extensible, pudiendo crearse nuevos proveedores que faciliten el trabajo con
otros origenes de datos.
El nucleo de ADO.NET, por tanto, debe estar preparado para operar con pro-
veedores que no conoce de antemano. Esto es posible gracias a la existencia de
unas interfaces genericas, predefinidas en el Ambito system. Data, que todo pro-
veedor de datos, ya sea directa o indirectamente, debe implementar.
Las interfaces de System. Data pueden dividirse en dos grupos: aquellas que
aplicables a cualquier origen de datos, sea o no una base de datos relacional, y las
especificas para bases de datos relacionales. Las primeras inician su nombre, como
es habitual en todas las interfaces, con el prefijo I, mientras que las segundas em-
plean el prefijo I Db.
Como se ver6 en 10s puntos siguientes, las del segundo grupo suelen estar de-
rivadas de las del primero, contando con algunas implementaciones por defect0
alojadas como clases en el Ambito system. Data. Common.
5. Modelo de objetos
l l _ _ ~ _ _ l
Los origenes de datos de tip0 RDBMS son capaces de facilitar un cursor, un mo-
tor software que el cliente puede utilizar, en el caso de ADO.NET, para acceder a
Programacidn de bases de datos con V i s u a l Basic .NET
System.Data
IColurnnMapping IColurnnMappinqCollection
ColumnMapping ColumnMappingCollection
DataSetColumn
SourceColumn
System.Data.Common
SqlDataReader OleDbDataReader
System.Data
IDa taRecord IDa t a R e a d e r
Fieldcount Read ( )
Itern NextResult ( )
GetXXX ( ) Close ( )
OdbcDataReader
Microsoft.Data.Od bc
Figura 5.2. Cada proveedor de datos implementa una clase DataReader que
implementa 10s miembros de las interfaces I D a t a R e c o r d e I D a t a R e a d e r
Svstem.Data
IDa taAdapter I D b D a taAdapter
Fill ( ) SelectCommand
Update ( ) Insertcommand
Updatecommand
Deletecommand
DataAdapter
DbDataAdapter
System.Data.Common
P
L t
SqlDataAdapter
Svstem.Data.SalClient ~
-- - . ~ _ _ _ _ I _ _ ___
L O proveedores
~ de datos que acceden a origenes de tip0 RDBMS o bases de
datos de escritorio, la mayor parte de ellos, deben facilitar operaciones adicionales
como es la conexi6n con la base de datos, la definici6n de comandos y control de
las transacciones. Estas operaciones son especificas y diferentes en cada provee-
dor, per0 con el fin de facilitar, si es que desea, una codificaci6n independiente del
Prograrnacidn de bases de datos con Visual Basic .NET
S
~-
Tras leer 10s puntos anteriores, ya se habra hecho una cierta idea sobre la com-
posici6n de un proveedor de datos .NET y su funcionamiento. Cada proveedor se
compone de una serie de clases que implementan determinadas interfaces defini-
das en System. Data, ya sea directamente, como ocurre con las tratadas en el
5. Modelo d e objetos
Svstem.Data
IDbConnec tion IDbCommand ID b T r - d n s a ct i o n
Connectionstring CommandType IsolationLevel
open 0 CommandText Commit ( )
Close ( ) ExecuteReader ( ) Rollback ( )
Createcommand ( ) ExecuteNonQuery ( )
BeginTransaction ( )
II J
Figura 5.4. Cada proveedor cuenta con implementaciones especificas de las interfaces
IDbConnection, IDbCommand e IDbTransaction
Todo proveedor de datos debe constar, como minimo, de las clases necesarias
para:
0 Establecer una conexidn con el origen de datos.
Definir y ejecutar comandos.
Leer de un cursor unidireccional directamente desde el origen de datos.
0 Crear un DataSet a partir de un comando.
base de otras, personalizadas para cada proveedor de datos concreto. Estas clases
son DbDataPermission, DBDataPermissionAttribute, RowUpdated-
EventArgs y RowUpdatingEventArgs.
Otros mdtodos, a pesar de no contar con una interfaz gendrica ni derivar de una
clase comitn definida en system. Data. Common, tambidn existen en la mayoria
de proveedores, aunque su implementacih no es obligatoria. Las clases Sql-
CommandBuilder, OleDbCommandBuilder, OracleCommandBuilder y
OdbcCommandBuilder, cada una de ellas perteneciente a 10s cuatro proveedores
que ya conoce, basicamente son iddnticas de cara a1 programador aunque, como es
logico, internamente cada una de ellas funciona de manera distinta. Su finalidad
es generar las sentencias necesarias para insertar, actualizar y eliminar informa-
ci6n del origen de datos, para lo cual disponen de 10s mdtodos GetInsert-
Command ( ) , Getupdatecommand ( ) y GetDeleteCommand ( ) . Lo que se obtiene
es un comando de insercih, actualizacih o borrado especifico para el proveedor
en el que estemos trabajando, de tal forma que una misma llamada, por ejemplo a
Get InsertCommand ( ) , generaria una sentencia distinta segitn que el origen de
datos sea SQL Server, Oracle o un controlador OLE DB u ODBC.
Algo similar ocurre con las clases Parameter,ParameterCollection y Error,
si bien esta ultima no existe en el proveedor de Oracle y, en su lugar encontramos
la clase OracleException.
Por ultimo, cada proveedor aporta sus clases exclusivas, inexistentes en 10s de-
mas proveedores, enfocadas a aprovechar las caracteristicas propias de un cierto
origen de datos. Su USO, no obstante, resulta mucho menos habitual puesto que, en
cierta medida, limita o hace mas dificil una posible transicion futura a otro produc-
to de almacenamiento de datos.
0 Relations: Si el conjunto de datos cuenta con varias tablas, entre ellas ne-
cesariamente existirAn relaciones. Esta propiedad es una referencia a un ob-
jet0 DataRelationCollection que aloja todas esas referencias.
0 Haschanges ( ) : Devuelve True en caso de que haya alg6n cambio en el
conjunto de datos, ya sea de insercibn, modificaci6n o eliminaci6n. Estos
Prograrnacidn de bases d e datos con V i s u a l Basic .NET
Mediante la propiedad Rows se tiene acceso a las filas de datos actuales, pu-
diendose modificar su contenido o eliminarse. Si queremos aiiadir filas se emplea
el metodo NewRow ( ) del propio objeto DataTable. Los cambios efectuados pue-
den aceptarse, con Acceptchanges ( ) , o descartarse, llamando a Re] ectChan-
ges ( ) . Utilizando el metodo Select ( ) es posible filtrar las filas de la tabla,
obteniendo s610 aquellas que se ajustan a un cierto criterio.
A1 igual que otras muchas clases, DataTable dispone de multiples eventos.
Con ellos se notifica el cambio del contenido de una columna, el cambio en una fila
o la eliminaci6n de una fila. Todos estos eventos tienen una forma en gerundio y
otra en pasado, por ejemplo RowDeleting y RowDeleted, produciendose el
primer0 en el momento en que va a efectuarse la acci6n y el segundo una vez que
se ha completado.
Fi las
Las filas de datos de una tabla, tal y como se ha indicado en el punto anterior,
se representan mediante objetos DataRow alojados en la colecci6n Rows. Como en
toda colecci6n, es posible aiiadir nuevos elementos, acceder a 10s existentes y
eliminarlos. Una vez tengamos una referencia a un DataRow, a una fila de datos
propiamente dicha, utilizariamos 10s miembros de dicha clase para manipular su
contenido.
Cada fila se encontrar6, respecto a1 estado original de la colecci6n de filas a la
que pertenece, en un determinado estado. h e se aloja en la propiedad s610 de
lectura Rows tate, indicando si se ha modificado, permanece sin cambios, ha sido
aiiadida o eliminada. Las operaciones bisicas que podemos llevar a cab0 sobre la
fila, y que provocan el cambio de su propiedad Rows t a t e, son las enumeradas a
continuacibn:
0 Afiadir una fila. Tomando como base la propiedad Rows del DataTable,
que contiene una referencia a una colecci6n, no tenemos m6s que usar el ha-
bitual metodo Add ( ) de cualquier colecci6n para aiiadir una nueva fila.
Eliminar una fila. Basta con llamar a su metodo Delete ( ) .
0 Modificaci6n del contenido de una fila. La clase cuenta con una propiedad
llamada ~tem, que es la propiedad por defecto, mediante la cual es posible
acceder a cada columna de la fila, ya sea mediante su nombre o con el indice
de posici6n que ocupa en la fila. Este acceso permite tanto leer el valor ac-
tual como cambiarlo.
Programacidn de bases de datos con Visual Basic .NET
A medida que se modifican 10s valores de las columnas de una fila, se iran eje-
cutando automaticamente todas las comprobaciones y restricciones que haya defi-
nidas en el conjunto de datos. Esto, en ocasiones, puede no ser lo mas adecuado,
especialmente si van a hacerse muchos cambios que tienen restricciones y, ade-
mas, dichos cambios tienen interdependencias que pudieran causar estados invali-
dos. De ser asi, antes de iniciar las modificaciones deberiamos llamar a1 metodo
BeginEdit ( ) del DataRow, inhibiendo tanto las comprobaciones como la gene-
raci6n de 10s eventos de cambio. Cuando hayamos terminado de manipular la fila,
confirmaremos todos 10s cambios con una llamada a EndEdi t ( ) . Sera en ese mo-
mento cuando se ejecuten todas las restricciones y produzcan 10s eventos. Tam-
bi4n puede utilizarse el m6todo CancelEdi t ( ) para devolver la fila a su situaci6n
inicial.
Las restricciones y tipos de datos de las columnas pueden dar lugar a que, tras
una modificaci6n, una o mas columnas queden en estado de error. La clase DataRow
dispone de la propiedad HasErrors, que nos permite saber si existen o no erro-
res, y el metodo GetColumnsInError ( ) , que devuelve un arreglo con todas las
columnas que tienen errores, pudiendo obtenerse la descripci6n del error.
Nota
A medida que van editandose, las filas de una tabla pueden contar con multi-
ples versiones de valor que almacenan, por ejemplo el valor por defecto, el que
tenia anterior a1 cambio y el posterior. El metodo Hasversion ( ) permite
saber si un cierto DataRow tiene 0 no multiples versiones del valor, en caSO
afirmativo puede accederse a ellos utilizando 10s valores de la enurneracion
DataRowVersion.
Cada una de las columnas existentes en un DataRow cuenta con una serie de
atributos que definen, por ejemplo, el tip0 de informaci6n que puede contener, el
valor por defecto si es que existe, si 10s valores que contendra deben ser 6nicos o
no, etc. Todos estos atributos son accesibles mediante 10s miembros de la clase
Da ta Co 1umn.
De esta clase nos interesarin basicamente una docena de sus propiedades, ya
que el resto de 10s miembros son heredados de las clases ascendientes y no tienen
que ver directamente con el trabajo con datos.
Algunas de esas propiedades son:
ColumnName: Nombre de la columna.
DataType: Tip0 de dato de la columna.
0 MaxLength: Longitud maxima si la columna contiene una cadena de texto.
5 . Modelo de objetos
__ - _-
Una de las propiedades de DataTable,llamada Constraints,es la encarga-
da de contener la coleccion de restricciones a aplicar a la tabla, estando definida
cada una de ellas mediante 10s miembros de una clase derivada de Constraint.
Esta, clase abstracta en la que se define la propiedad ConstraintName que alber-
gar5 el nombre de la restriction, es base de las clases ForeignKeyConstraint y
Uniquecons t raint, que representan 10s dos tipos de restriccih m5s habituales.
La clase Uniqueconstraint, aiiadida a la coleccion Constraints de la ta-
bla, asegura que 10s valores que tiene una cierta columna Sean siempre unicos en
todas las filas. Crear un objeto Uniqueconstraints y afiadirlo a la citada colec-
cion es exactamente igual que dar el valor True a la propiedad Unique del Data-
Column que representa a la columna cuyos valores tienen que ser unicos.
Las restricciones de clave externa, correspondientes a la clase ForeignKey-
Constraint,son m5s complejas. A1 crearse relacionan una columna de una tabla
con una columna de otra tabla, impidiendo la inconsistencia de sus valores. Ade-
m5s, esta clase dispone de dos propiedades, UpdateRule y DeleteRule,que es-
tablece qu6 debe hacerse cuando se modifique o elimine, respectivamente, el valor
de una columna en la tabla maestra que tienen dependencias en la tabla de detalle.
DataRelation, cretindose un objeto a partir de ella por cada relacion que exista
en el conjunto de datos. Una vez se ha establecido una relacion entre las tablas, se
evitar6 cualquier actuaci6n sobre ellas que pudiera infringirla, garantizando la in-
tegridad de la informacion.
Las propiedades de DataRelation suelen establecerse en el momento de la
creacion del objeto, facilitando a1 constructor 10s partimetros apropiados. Para ello
se entrega el nombre de la tabla maestra y la columna o columnas que actuan como
clave principal, asi como el nombre de la tabla de detalle y el de la columna o co-
lumnas que actuarian como clave externa. Estos valores tambikn pueden ser esta-
blecidos con las propiedades ParentTable, Parentcolumns, ChildTable y
Chi IdColumns, respectivamente.
A1 crear una relacion 6sta genera implicitamente dos restricciones que se apli-
can a las tablas participantes en dicha relacion. Por una parte, se aplica una restric-
ci6n Uniqueconstraint a la columna indicada de la tabla maestra, a fin de que
no pueda repetirse su valor ya que, de ocurrir esto, tendriamos un conflict0 por-
que no se sabria a quk fila de la tabla maestra corresponden las de la tabla de de-
talle. Por otra parte, tambien se crea una restriccion ForeignKeyConstraint
aplicada a la columna de la tabla de detalle, impidiendo asi que se introduzcan va-
lores inexistentes en la tabla maestra.
En la figura 5.5 puede ver un esquema de bloques en el que se representa un
DataSet con dos DataTable, relacionados mediante un DataRelation, conte-
niendo cada uno de ellos sus DataRow, Datacolumn y Constraint, accesibles
mediante las propiedades comentadas en todos 10s puntos anteriores.
Un objeto DataTable facilita en su propiedad Rows todas las filas que contie-
ne la tabla del origen de datos a1 que estti asociado, ofreciendo una vista por defec-
to. No obstante, partiendo de ese objeto DataTable es posible crear vistas de
datos mtis elaborados gracias a la clase Dataview.Mediante un objeto DataView
las operaciones de busqueda, ordenaci6n y manipulacion de 10s datos resultan
mds sencillas, ya que dispone de las propiedades y mktodos apropiadas para ello.
Los criterios de filtrado y el orden pueden fijarse durante la creacion del Data-
View o bien posteriormente, sirvikndose de las propiedades RowFil ter, Row-
StateFilter y Sort. La primera contendrti una cadena de caracteres con las
condiciones de filtrado de filas, la segunda aplica un filtro basado en el estado de
las filas y la tercera determina las columnas sobre la base de las cuales se ordena-
rtin las filas de la tabla.
Teniendo las filas ordenadas, operaciones como la busqueda resultan mucho
mds f6ciles. Usando 10s mktodos Find ( ) y FindRows ( ) de DataView es posible
encontrar la fila o filas que coinciden con el valor clave que se indique, busctindolo
en la columna por la que estti ordentindose. Tambidn pueden usarse 10s mktodos
AddNew ( ) y Delete ( ) para adadir y eliminar filas, asi como editar 10s valores de
las existentes accediendo a ellas mediante la propiedad I tem.
5. Modelo de objetos
II DataTable
II DataTable
DataSet
Figura 5.5. U n conjunto de datos formado por dos tablas relacionadas entre si,
compuesta cada una de ellas de filas, columnas y restricciones
Tras instalar Visual Studio .NET tenemos a nuestra disposici6n dos proveedores
de datos: SqlClient y O l e D b . El primer0 es especifico para SQL Server, mientras
que con el segundo es posible emplear cualquier controlador OLE DB instalado en
el sistema, tema sobre el que volveremos despuks. Acceder a un cierto origen de
datos mediante el proveedor OleDb y un controlador OLE DB supone, como es
facil deducir, una capa mas de cbdigo, lo cual implica mayor us0 de recursos y me-
nor rendimiento. Por ello, siempre que sea posible es preferible el us0 de provee-
dores de datos nativos y especificos para cada origen.
6 . Conexidn a1 origen de datos
El primer paso seri localizar 10s proveedores adicionales que haya publicado
Microsoft, en este momento 10s que acaban de indicarse, y transferirlos a nuestro
ordenador. Vaya a la sede M S D N Library de Microsoft introduciendo este URL
http: //msdn.microsoft.com/library/ en su cliente Web habitual. Desplie-
gue la secci6n del menu que aparece a la izquierda el apartado Downloads y selec-
cione la opci6n Developer Downloads. En el panel de la izquierda habr6 aparecido
una lista jerirquica con distintos nodos. Abra el nodo .NET Framework y alli en-
contrari 10s proveedores, por ejemplo en ODBC .NET Data Provider y Microsoft
.NET Data Provider for Oracle.
A1 seleccionar uno de 10s nodos, aparecer6 un documento facilitando diversa
informaci6n y un enlace para obtener el archivo de instalaci6n del proveedor. En
la figura 6.1, por ejemplo, puede ver el documento del proveedor para Oracle, con
el enlace en la parte superior derecha. Obtenga el archivo y repita el paso con el
proveedor ODBC.
~~~~~
F F
NET Framework
custom s e t u p
select the way you want k a t u r s to be mrtakd
1- Miuosoftaade .M€TDataFravdef
Component I
7 I D b Connec tion
Sqlconnection
. ~ ~ x I ~ _ _ _ - ~ _ _ _ _ _ _
~ ~ _ _ I ^ l_^-...-_l__l_^___l_----------
_ -
Tras abrir la conexion, con el comando Open ( ) , se conecta con una base de
datos o archivo que dependera de 10s parametros facilitados en la cadena de
6. Conexidn a1 origen de datos
conexion. Puede cambiarde una base de datos a otra, sin necesidad de cerrar
la conexion y volver a abrirla, mediante el metodo ChangeDatabase ( ) .
Los nombres de 10s controladores ODBC suelen ser mucho mfis descriptivos
que 10s anteriores. Para utilizar el controlador para Access u Oracle, por continuar
con 10s mismos ejemplos propuestos, usariamos 10s identificadores { Mi c r o s o f t
A c c e s s D r i v e r ( * . m d b ) } y { M i c r o s o f t ODBC f o r O r a c l e } , respectiva-
mente. Observe que se han utilizado unas llaves para delimitar a 10s identificado-
res, llaves que hay que incluir en la cadena de conexion.
A continuacion, suponiendo que ConnOleDb tiene una referencia a un objeto
O l e D b C o n n e c t i o n , puede ver varios ejemplos de selection de controlador. Ten-
ga en cuenta que estas cadenas de conexion no son vhlidas, ya que ademfis del con-
trolador son precisos parfimetros adicionales antes de poder llamar a Open ( ) para
establecer la conexion.
' C o r l t r c , l a d o r ODBC p a r a S Q I , S e r v e r
C o n r ~ O d h c . ~ o n n e c t i r ~rr i~nSgt = " D r i v e r = { S Q L S e r v e r ] .
Nota
Ademas de 10s controladores OLE DB y ODBC que se instalan por defect0 con
Windows y ciertos productos, como Visual Studio .NET, existen otros, desarro-
llados por terceros fabricantes, para facilitar el acceso a sus productos. En:
h t t p :/ / 1.1 rw'>r 1d . ccrmpus e r ve . ci.rn/ tiornepat~
e s / Ken N o r t h / ~
i) 1e r i b V e n .h t m
puede encontrar una lista de productos relacionados con OLE DB, principal-
mente controladores, y en:
h t t F) : / / o u rwci r 1d . c ompii s e r v e . corn / h o m s p a g e s / K e rl N 0I-t h / O D B C V e rlii . H TM
~
_ _ _ _ l l l __--__-
~~- __-
__ ___-_- ~ -- --^___- ^I l ~ _ l l _ _ _ _ _ I _ _ - - ~ --
El siguiente paso, el primer0 si vamos a usar Sqlclient u Oracleclient, es
identificar el origen de datos que, en ocasiones, ser6 un determinado servidor en
el que se encuentra ejecutrindose el RDBMS o bien un nombre de archivo. El nom-
bre de la propiedad es Data Source o Server, dependiendo del proveedor. La
primera existe en OleDb, SqlClient y Oracleclient, mientras que la segunda
aparece en Odbc y tambien SqlClient y Oracleclient.
Si la cadena de conexi6n que estamos estableciendo es de un objeto Sqlclient
u Oracleclient, la propiedad Data Source contendra el nombre de la m6qui-
na en que est6 ejecut6ndose el servidor de datos. En mi caso, por poner un ejem-
plo, el ordenador en el que esta instalado Visual Studio .NET, y desde el que se
ejecutan las aplicaciones, es un equipo llamado Dimension, mientras que SQL
Server est6 ejecut6ndose en otro con el nombre Inspiron. La cadena de conexi6n
de un objeto SqlConnection seria la siguiente:
Data S o u r c e = i n s p i r o n
..__._____
........ _. ........ ._ ......_II_..
. . __.._...... .
.I .,..._I
Para acceder a una base de datos Access o una hoja de c6lculo Excel basta con
conocer el nombre del archivo en que se encuentra, per0 a1 trabajar con un RDBMS,
como Oracle o SQL Server, no basta con conocer el nombre del ordenador en el que
est6 ejecut6ndose el servidor. AdemAs, es precis0 que indiquemos sobre cu61 de las
bases de datos existentes en 41 deseamos trabajar.
Los proveedores OleDb y Sqlclient admiten en la cadena de conexi6n la
propiedad I ni tia1 Cat a1og,a la que se asignaria el nombre de la base de datos.
Si utilizamos el proveedor Odbc, la propiedad a usar es Database.
' P r o v e e d o r Oracle
Con nor a c 1e . Con rl e ct i on St r ing =
"Data Source=ek400; User ID=scott; Fassword=tiger"
A1 final del punto anterior, tras revisar 10s distintos par6metros que pueden
formar parte de una cadena de conexih, se han propuesto varias asignaciones
distintas para la propiedad Connectionstring de varios objetos Connection.
S610 con esto ya estariamos en disposici6n de conectar con el origen de datos, que
es lo que perseguimos, llamando a1 m6todo Open ( ) inmediatamente despu6s de
la asignaci6n.
Si la cadena de conexi6n tiene el formato correct0 y, adem&, la configuraci6n
de red, el estado del servidor y otros par6metros permiten conectar con el origen
de datos, la propiedad State deberia cambiar de Closed a Open. Cualquier in-
cidencia que impida la conexi6n provocara una exception, por ejemplo Argumen t-
Exception si hay un parametro incorrect0 en la cadena de conexion.
En 10s puntos siguientes va a tratarse, paso a paso, el proceso para conectar con
algunos de 10s origenes de datos creados en un capitulo previo, comprobando esa
conexi6n y cerrindola finalmente. El resultado no sera muy espectacular, per0 es
el primer paso en el tratamiento de datos con ADO.NET.
~-
ss
Vamos a comenzar por uno de 10s casos m6s simples, escribiendo un pequefio
ejemplo en Visual Basic .NET que conecte con la base de datos Access que habiamos
creado en el tercer capitulo. Para ello no es necesario que en el ordenador donde
est6 la base de datos, y va a ejecutarse este ejemplo, se encuentre instalado Microsoft
Access, basta con la instalaci6n de 10s MDAC.
Por simplicidad, estos primeros ejemplos van a crearse como aplicaciones de
consola. Simplemente genere una aplicaci6n de consola vacia, utilizando el asis-
tente Aplicacion de consola, y a continuaci6n introduzca el c6digo indicado que,
en este caso, seria el siguiente:
Imports Systern.Data.OleDb
6. Conexidn a1 origen de datos
Module Module1
Sub M a i n ( )
, >
Dim CorlnOleDb As New OleDbConnection ( )
C n n n O 1 e ~ b . C ~ n n e c t i o n S t r i n=g
" P r o v i i ~ r = M i c r o s o f tJet.OLEDB.4.0;
. " &
"Data Source-\PBddVisualBasicNET\Capp03\Libros.nidb"
CorlnOleDb.C
Else '
End I f
Catch '
sole.WritPLine["*** Error a 1 irlterltar l a c u n e x i u n * * * " 1
End T r y
End Sub
End Module
Figura 6.4. Conseguimos conectar sin problemas con una base de datos Access
El mismo controlador OLE DB que hemos utilizado para conectar con Microsoft
Access, Microsoft. Jet.OLEDB. 4. 0, nos servir6 tambien para acceder a cual-
quier hoja de c5lculo Excel. Lo unico que tenemos que hacer es cambiar la cadena
de conexibn, facilitando el camino y nombre del libro.
Ademds, tendremos que usar el pardmetro Extended Properties,utilizado
para enviar a1 controlador pardmetros exclusivos, indicando que lo que va a abrir-
se es una hoja de Excel y, opcionalmente, si la primera fila de cada hoja contiene ti-
tulos de columnas o no.
Tomando como base el c6digo anterior, cambie la asignaci6n a la propiedad
Connectionstring para que quede como se muestra a continuacih:
C o n n O l e D b . ConnectionString = -
"Provider=Microsoft.Jet.OLEDB.4.0; " & -
"Data S o u r c e = \ P B d d V i s u a l B a s i c N E T \ C a p _ 0 3 \ L i b r o s . ~ l s ; " &
"Extended Properties-'Excel 8.0; HDR=Yes"'
Observe c6mo las propiedades extendidas, que en este caso indican que el
archivo es un libro de Excel que cuenta con una cabecera de titulos, se delimitan
entre comillas simples. De no hacerlo asi, el pardmetro HDR=Yes pasaria a1 pro-
veedor OLE DB de ADO.NET, que intentaria interpretarlo y, a1 no reconocerlo,
provocaria un error. Con el entrecomillado conseguimos que ese pardmetro, jun-
to con Excel 8 . 0, pase directamente a1 controlador OLE DB de Microsoft Jet.
6. Conexidn a1 origen de datos
___
Nota
Tanto Access como Excel son origenes de datos a 10s que se accede localmente,
sin necesidad de utilizar un software cliente para, a trav4s de protocolos de red,
comunicarse con un servidor que se encargue de efectuar fisicamente la manipula-
ci6n de 10s datos. De ahi que la conexi6n sea bastante sencilla, como acaba de ver-
se en 10s dos puntos previos.
Para poder conectar con nuestra base de datos SQL Server deben darse 10s si-
guientes requisitos:
0 El servidor SQL Server, ya sea 7,2000 o MSDE, debe estar en funcionamien-
to, bien en el mismo ordenador donde va a ejecutarse la aplicaci6n o en un or-
denador remoto al que se tenga acceso mediante una infraestructura de red.
En el equipo donde va a ejecutarse la aplicaci6n debe haberse instalado el
software cliente de SQL Server. Esto no es necesario si es el mismo equipo
donde est6 ejecut6ndose el RDBMS o bien se trata de un ordenador donde se
ha instalado la plataforma .NET y la ultima versi6n de 10s MDAC, que ser6
nuestro caso.
Programacidn de bases de datos con Visual Basic .NET
Hay que conocer el nombre del servidor donde est6 ejecut6ndose el RDBMS,
asi como disponer de una cuenta, nombre de usuario y clave, para poder co-
nectar con 61 en caso de que no vaya a utilizarse la seguridad integrada.
En caso de que vayamos a ejecutar el ejemplo siguiente en el mismo equipo
donde estii ejecutiindose el servidor, podemos cambiar el valor de Data Source
por localhos t.En mi caso SQL Server se ejecuta en una miiquina distinta, de ahi
que sea precis0 indicar su nombre. Ademiis, va a utilizarse la seguridad integrada
de Windows, empleando nuestra cuenta de acceso a1 sistema cliente para identifi-
carnos ante el servidor y poder acceder a1 RDBMS.
Asumiendo que se cumplen todos 10s requisitos previos, y que hemos compro-
bad0 que es posible el acceso desde el cliente a1 servidor utilizando el software
cliente de SQL Server, 10s pasos para conectar con la base de datos, partiendo del
c6digo del punto anterior, serian 10s indicados a continuaci6n:
Sustituci6nde System.Data.0leDb por System.Data.SqlC1ient e n l a
instrucci6n Imports, a1 inicio del m6dulo de c6digo.
0 Modificacion de la declaraci6n de la variable de conexion, que quedaria asi:
Dim ConnSql As New SqlConnection( -
" D a t a S o u r c e = i n s p i r o n ; Integrated Security=SSPI; " & -
" I ni t 1 a 1 Cat a log=Li bros " )
Por lo demis, la configuraci6n para poder conectar con nuestra base de datos
InterBase, creada en el tercer capitulo, no difiere de la explicada en el punto ante-
rior para SQL Server, siendo precis0 tener el RDBMS en funcionamiento, ya sea en
el equipo local en un servidor, el software cliente instalado en el ordenador donde
vaya a utilizarse la aplicacidn y la configuracibn correcta de red para comunicar
cliente con servidor.
A pesar de que la facilidad de us0 del RDBMS Oracle ha ido mejorando de ver-
si6n a versibn, hasta llegar a las actuales 8i y 9i, lo cierto es que resulta un product0
6 . Conexidn a1 origen de datos
bastante mds complejo que cualquiera de 10s tratados en 10s puntos previos. El
proceso de conexih, desde el cbdigo, no difiere del utilizado en 10s ejemplos an-
teriores, pero, para que funcione, es precisa una preparacidn preliminar configu-
rando 10s servicios en el software cliente.
r- ConriguraciCln de Listener
I k i c t e n t e de Cdnfigiirnrion dp Red de Orarlp: Configurnrinn del Nombrp dPI %=rvicio de ... f?:;
Una vez que el asistente conoce todos 10s parAmetros necesarios, en el paso si-
guiente se ofrece la posibilidad de efectuar una prueba de conexih. Seleccione la
6. Conexidn a1 origen de datos
opci6n Si, realizar una prueba y pulse el b o t h Siguiente. El resultado obtenido de-
beria ser el de la figura 6.10. Si obtiene un error revise toda la configuraci6n previa
pulsando el b o t h Anterior.
Carnbiar Conexid"]
-
Por tiltimo, antes de volver a1 inicio del asistente, tendri que introducir el nom-
bre de servicio local para acceder a esta configuracih. Introduzca Libros y pul-
se el b o t h Siguiente. Salga del asistente, ahora ya est6 en disposici6n de introducir
el c6digo Visual Basic .NET para conectar con la base de datos.
Al igual que con el proveedor ODBC, es precis0 agregar en el proyecto una re-
ferencia al ensamblado que contiene el proveedor para Oracle, el ensamblado
System.Data.OracleClient.dl1.
El c6digo base utilizado en todos 10s ejemplos anteriores tendr6 que sufrir las
modificaciones siguientes:
Prograrnacidn de bases de datos con Visual Basic .NET
En 10s cuatro ejemplos del punto anterior, conectando con diversos origenes de
datos, hemos introducido siempre 10s parfimetros de conexi&, tales como nombre
de servidor, usuario y clave, directamente en la propia cadena de conexi6n. Esto,
6 . Conexidn a1 origen de datos
Los DSN siempre tienen el mismo objetivo y cuentan con 10s mismos parGmetros,
per0 la forma en que se almacenan hace que pueda hablarse de tres categorias di-
ferentes de DSN:
De usuario. La informacih se almacena en el registro de Windows, concre-
tamente en la rama perteneciente a un determinado usuario. De esta forma,
ese DSN s610 puede utilizarlo el usuario a1 que pertenece.
0 De sistema. Similar a1 anterior, dado que se almacena en el registro, per0 no
asociado a un usuario en particular, sino en la secci6n general del sistema.
Un DSN de sistema puede ser utilizado por cualquier usuario.
0 De archivo. En vez de en el registro de Windows, la informacidn de conexion
se almacena en un archivo, lo cual permite transportarla a 10s equipos en 10s
que pueda ser necesaria sin precisar la modificacih del registro en todos
ellos.
Elegir un tip0 u otro depended directamente de las necesidades de cada proyec-
to. En cualquier caso, recuerde que un DSN puede utilizarse tan so10 desde ODBC,
no resultando Gtil con 10s otros proveedores ADO.NET.
que en las piiginas DSN de usuario, DSN de sistema y DSN de archivo encontrarii
10s DSN de cada tip0 existentes en este momento.
Seleccione la pdgina DSN de sistema y pulse el b o t h Agregar. Elija de la ven-
tana que aparece, con una lista de todos 10s controladores, el controlador Microsoft
Access Driver (*.mdb), haciendo doble clic sobre el. Entonces verii la ventana Con-
figuration de ODBC Microsoft Access (v6ase figura 6.13) en la que debe introducir
el nombre que va a dar a1 origen de datos y todos 10s demds pariimetros. En este ca-
so bastard con pulsar el b o t h Seleccionar y facilitar el camino y nombre del archi-
vo de Microsoft Access que ya habiamos empleado anteriormente como ejemplo.
400601900 Wansoft1
400601900 MmosoftI
400601900 Marsdt
400601900 Marsoftl
1000200 t&msoftI
1000005 IBPhoenu
2 01 22 01 No rnrXCi
400601900 Marsoft1
T&
& kce= rmm) 400601900 t&msoftl[d
1- w
Figura 6.12. El Administrador de origenes de datos ODBC cuenta con multiples paginas
WknpaadepSgna 15 T ~ A S I W W ~
En caso que desee asociar una cuenta de usuario y clave con el DSN, evitando
que la aplicacion o el propio usuario tenga que facilitar esta informacion, pulse
el boton Avanzadas de la ventana Configuracion de ODBC Microsoft Access.
Para terminar, pulse el boton Aceptar del cuadro de dialog0 anterior. Volvera a
la pdgina DSN de sistema del Administrador de origenes de datos ODBC, en cuya
lista debe aparecer el DSN r e c i h creado.
c
Una vez que tenemos creado el DSN en el equipo donde va a ejecutarse la apli-
cacibn, utilizarlo desde &a, con el proveedor Odbc, es realmente sencillo. Tome
el ejemplo anterior en el que ustibamos este proveedor para acceder a una base de
datos InterBase, cambie la cadena de conexi6n facilitada a1 constructor dejdndola
como "DSN=Libros" y ejecute el programa. El resultado deberia ser el de la figu-
ra 6.14. Ha conectado con Microsoft Access mediante ODBC facilitando s610 el nom-
bre de un DSN.
Observe que ahora la propiedad Database facilita el camino en el que se en-
cuentra el archivo, asi como su nombre sin extensi6n.
- --__ - -
Rowedom dc OLE DB
Micros& ISAM 1 1 OLE DB Provider
0 Vaya a la psigina Todas y haga doble clic sobre la propiedad Extended Pro-
perties, en la lista que aparece en el sire, central de la ventana.
0 La ventana Modificar valor de propiedad nos permite introducir el valor que
deseamos dar a la propiedad Extended Properties. En este caso, como
puede verse en la figura 6.16, escribimos la secuencia Excel 8 . 0 ;HDR=Yes
y pulsamos el b o t h Aceptar.
I/
Utilizar el archivo udl desde una aplicaci6n propia es tan f6cil como usar un
DSN. Abra el proyecto en el que, mediante el proveedor OleDb, conect6bamos con
una hoja de c6lculo Excel. Cambie entonces la cadena de conexih, asignada en es-
te caso a la propiedad ConnectionString, dejhndola como "File Name=. . \
Conexion. udl".A1 ejecutar el programa se obtendria una conexi6n satisfactoria,
si bien en este caso la propiedad Database no nos indica el origen de datos a1 que
estamos conectados.
Como ha podido ver en este capitulo, mediante las clases Connection de ca-
da uno de 10s proveedores ADO.NET es posible conectar virtualmente con cual-
quier origen de datos, tanto RDBMS como no RDBMS. Por una parte tenemos dos
proveedores especificos, Sqlclient y Oracleclient, capaces de comunicarse
directamente con SQL Server y Oracle, respectivamente. Por otra, 10s proveedores
OleDb y Odbc abren las puertas a1 us0 de cualquier controlador OLE DB u ODBC
que pudiera existir, facilitando el acceso a Microsoft Excel, Microsoft Access o In-
terBase, pero tambie'n a dBase, Paradox, Sybase, DB2, MySQL y, en general, cual-
quier base de datos.
Ahora que ya conocemos la sintaxis general de las cadenas de conexih, asi co-
mo 10s miembros de la interfaz IDbConnection que permite abrir, cerrar y com-
probar la conexion, estamos en disposicion de empezar a recuperar datos desde el
origen a1 que se haya conectado. Este serd el objetivo del pr6ximo capitulo.
La mayoria de las aplicaciones que tratan con datos, una vez que han conectado
con el origen solicitan directamente la informacih que precisan o ejecutan 10s co-
mandos pertinentes. Estas aplicaciones, por regla general, ya conocen de antema-
no la estructura de la base de datos, ya que &ta, habitualmente, estaba disponible
cuando el equipo de desarrollo planific6 la aplicacih. Este escenario podriamos
denominarlo como normal. No obstante, las excepciones tambien existen en este
campo y es posible que a1 crear nuestra aplicaci6n desconozcamos 10s nombres de
las tablas o columnas. Es un caso que se da, sobre todo, cuando el programa no
esti construido especificamente para operar sobre un cierto origen de datos sin0
que, por el contrario, debe facilitar el acceso a cualquier estructura de informa-
ci6n. Es el caso tipico a1 escribir alguna utilidad general para un RDBMS 0,como
en este capitulo, cuando quiere simplemente experimentarse para conocer c6mo
conseguir una determinada informacih.
El objetivo de este capitulo es describir el proceso a seguir para obtener infor-
maci6n de esquema de una base de datos, utilizando para ello 10s servicios del
proveedor ADO.NET 0,si este carece de ellos, 10s especificos del origen con el que
vaya a tratarse.
i cion de esquerna?
Salvo excepciones, como es el caso de las hojas de cilculo Excel, todos 10s ori-
genes de datos almacenan, aparte de 10s datos propiamente dichos, informacih
7. Informacidn de esquema de la base de datos
sobre la estructura de 6stos. Todos 10s RDBMS, las bases de datos locales e, inclu-
so, 10s archivos XML utilizan esta informaci6n de esquema para saber cu6les son
las tablas existentes, con qu6 columnas cuentan, qu6 tip0 de dato corresponde a
cada una de ellas, etc.
Si conectamos con un origen de datos cuya estructura desconocemos, la recu-
peraci6n de la informaci6n de esquema, tambi6n conocida como meta-informacidn,
nos permitir6 adaptar diniimicamente el funcionamiento del programa para que
trate 10s datos apropiadamente.
Los proveedores ADO.NET no cuentan con servicios que faciliten la recupera-
ci6n de informaci6n de esquema, ya que su finalidad es ser lo m6s simples y efi-
cientes posible, facilitando asi tambien el desarrollo de nuevos proveedores.
Para recuperar la informacih de esquema de la base de datos, por tanto, ten-
dremos que recurrir a medios alternativos. Existen biisicamente dos: utilizar 10s
servicios del controlador OLE DB, si es que vamos a usar el proveedor ADO.NET
OleDb, o servirnos de las instrucciones que el propio origen de datos facilite para
obtener esa informacibn. En 10s puntos siguientes vamos a tratar ambos casos.
bera constar de cuatro elementos: nombre del catalogo a consultar, nombre del es-
quema, nombre de la tabla y tip0 de la tabla. La mayoria de 10s valores pueden ser
nulos. Si no se indica un catalogo, por ejemplo, se retornan todas las tablas de to-
dos 10s catalogos. Para obtener todas las claves primarias de una tabla, otro ejem-
plo, 10s parametros serian tres: el nombre del catalogo, el del esquema y el de la
tabla cuya clave primaria deseamos recuperar.
D i m C o r l n O l e D b As New OleDbConnection ( )
D i m TblResultado As DataTable
D i m F i l a As D a t a R o w , C o l u r n r l a As D a t a C o l u r n n
Si conocemos 10s datos que van a devolverse, en lugar de mostrarlos todos po-
demos obtener solo aquellos que m6s nos interesan. A1 recuperar una lista de ta-
blas existentes en el origen, por ejemplo, recuperariamos el nombre de cada tabla
con Fila ( "TABLE -N A M E " ) , sin necesidad de recorrer todas las columnas.
Dim T b l R e s u l t a d o As D a t a r d b l e
Dim Fila As D a t a R i w , ColiJrnrla As D a t d r c l u m n
TblResultado = ConnO1eDb.LetOleDbSc h e m a T a b l c = ( ~
OleDbSchemaGuid.Tablp5, ~
Disponiendo de esta funcibn, lo irnico que tenemos que hacer es afiadir a1 m4-
todo Main ( ) las dos sentencias siguientes:
, r,
L r
MuestraEsquerna ("Ho]a de
"Provider=Microsoft. Jet.OLEDB. 4.0; " &
" Da t a Source= \ PBddV 1 s u a 1B a s 1 cNE T \ Cap- 03\L 1b ro s . x 1s ; " &
"Fxtended Properties='Excel 8.0; HDR=Yes"')
t i
Como se indicaba antes, ninguno de 10s proveedores ADO.NET cuenta con me-
dios propios para recuperar la informacih de esquema del origen de datos si ex-
ceptuamos lo que acabamos de ver en el punto anterior. Para recuperar la lista de
tablas de una base de datos SQL Server u Oracle, utilizando sus respectivos pro-
veedores, tendriamos que utilizar las sentencias Transact-SQL o PL / SQL, respec-
tivamente, que procediesen.
Tendriamos que definir la cadena de conexi6n con la base de datos, ejecutar
una sentencia SQL y recoger el resultado que, como en el caso de G e t O l e D b S c h e m a -
T a b l e ( ) , seria un objeto DataTable. Como intermediario tendriamos que usar
un adaptador de datos, como si ejecutasemos cualquier sentencia SQL de recupe-
raci6n de informacih. Este es un tema del que nos ocuparemos mas adelante, con-
cretamente en el noveno capitulo, per0 en el siguiente ejemplo usaremos sendos
adaptadores para poder recoger la lista de tablas que hay en las bases de datos
SQL Server y Oracle.
Ambos RDBMS, SQL Server y Oracle, cuentan con una serie de tablas especia-
les en las que almacenan la informacih de esquema de la base de datos. Estas ta-
blas pueden ser consultadas, siempre que se cuente con 10s permisos adecuados,
como cualquier otra tabla, mediante una sentencia S E L E C T .
En el caso de SQL Server existe un esquema, llamado I N F O R M A T I O N SCHEMA,
en el que existen diversas tablas, como TABLES, COLUMNS, R O U T I N E S , etc. Pode-
mos ejecutar la sentencia S E L E C T * FROM I N F O R M A T I O N SCHEMA. TABLES, por
ejemplo, para recuperar todas las tablas de la base de datosTAlgunas de las colum-
nas de datos devueltas, relativas a las tablas, son TABLE CATALOG, TABLE NAME
y TABLE TYPE, que pueden ser usadas, en caso necesarioTpara filtrar el resatado.
Oracledispone de tablas similares, 1lamadasusER TABLES, U S E R VIEWS, U S E R
CATALOG, etc., mediante las cuales podemos recuperar diversa infGrmaci6n de la
base de datos. En el caso de U S E R TABLES, algunas de las columnas existentes son
TABLESPACE-NAME, TABLE-NAME, PCT -FREE y PCT -USED.
. . . . . . _ , . . , , . . ,
" .r.:- .. :
Module M o d u l e 1
Sub Main ( )
AdaptadorSql.Fill(TblResultado) '
~
1 , - 1
i _ ~ i i
TblFesultado = New D a t a T a b l e O
Adaptadororacle. Fill (TblResultado) '
End Module
1.1 I dl
Figura 7.2. Lista de tablas SQL Server y Oracle mostradas en el Bloc de notas
Programacion de bases de datos con Visual Basic .NET
Aunque en 10s ejemplos previos nos hemos limitado a recuperar una lista de las
tablas existentes en el origen de datos, en el caso de Excel y Access no hay mas ele-
mentos disponibles puesto que no 10s creamos en su momento, en la practica po-
driamos utilizar el mismo procedimiento para, por ejemplo, conocer cu6les son las
vistas predefinidas, si hay procedimientos almacenados, etc. Tomando como base
el ejemplo previo, que conecta con SQL Server y Oracle, pruebe usted mismo con
10s valores alternatives mencionados antes: INFORMATION-SCHEMA.VIEWS,USER-
VIEWS, etc., y asi conocer cuiles son 10s datos devueltos.
Si conociesemos tan solo el nombre de cada tabla o vista, sin mas, tampoco po-
driamos hacer mucho. La siguiente necesidad sers conocer las columnas de cada
una de esas entidades: nombre, tipo, etc. Aunque podriamos seguir empleando
metodos especificos de cada proveedor u origen de datos para obtener esta infor-
macibn, existe una alternativa m i s f6cil y, sobre todo, aplicable a cualquier origen
con el que se haya conectado.
La interfaz IDataReader, implementada por las clases DataReader de cada
proveedor, dispone de un metodo, llamado GetSchemaTable ( ) , que facilita un
DataTable con 10s datos de cada una de las columnas del conjunto de resultados
que va a leerse.
Este conjunto de resultados viene definido por un comando ejecutado previa-
mente con el metodo ExecuteReader ( ) de IDbCommand,interfaz implementada
por todos 10s comandos.
Descrito paso a paso, el proceso para obtener las columnas de cualquier tabla o
vista seria el siguiente:
Creacion de un nuevo comando, OleDbCommand, SqlCommand, Oracle-
Command u OdbcCommand, con una sentencia del tip0 SELECT * FROM
Tabla, donde Tabla seria el nombre de una de las tablas previamente ob-
tenidas en un DataTable. A1 crear el comando este se asocia directamente
con la conexi6n ya abierta con el origen de datos.
0 Llamada a1 metodo ExecuteReader ( ) del comando, facilitando como pa-
.
rametro CommandBehavior SchemaOnly. Asi solicitamos so10 la recupe-
ration de informaci6n de esquema, sin datos. El resultado devuelto por este
metodo es una referencia IDataReader que tendremos que almacenar en
una variable, ya sea de ese tip0 o del DataReader especifico del proveedor
que este utilizindose.
0 Llamada a1 metodo GetSchemaTable ( ) del DataReader, recuperando asi
en un DataTable toda la informaci6n de columnas sobre la tabla o vista
indicada.
que encontramos, por ejemplo, el nombre de cada columna, su tip0 original y tip0
.NET, precisi6n numkrica, si es o no unico, si es s610 de lectura, etc.
ConriOleDb.Open() '
TblResultado = ConnOleDb.GetOleDbSchernaTable( __
OleDbSchemaGuid.Tables, -
New Object( ) {Nothing, Nothing, Nothing, "TABLE"} )
ConnOleDh.Close ( 1 '
End Sub
ues r a o iimr
If NombreTaDla.EndsWith!"$") Then
Dim Lector A s I D a t a R e a d e r =
( C o m m a n j B i h a b l ir. S c h e m a O n l y )
Dim T b l h ~ ~ d l t a dAs
r DataTable = Ler-tnr. ( 7 e t S c h e r n a T a b l e !)
,
Dim F i l a As D a t a h o w
Console.Write(vbTab & N e w -
Str~nglFiiai”ColurnnNam~”)) . P a d R i g h t (15) & vbTab)
Console.WriteLine(Fiia (“DataType”))
Next
Lector.Close i 1 ’ . J
Nota
Puede utilizar el mismo camino para enumerar las columnas de las tablas SQL
Server, Oracle o bien InterBase. Una vez ejecutado el comando y obtenido el
DataReader,todo el proceso es identico.
Los proveedores de datos ADO.NET est6n diseiiados con una arquitectura que
es relativamente simple, facilitando su desarrollo y, sobre todo, potenciando el
rendimiento sobre 10s dem& aspectos. Esta es la raz6n de que en ellos no existan
metodos para acceder a la informaci6n de esquema de 10s origenes de datos, sien-
do precis0 utilizar medios mas especificos y, por lo tanto, dependientes de cada
origen en particular.
En este capitulo ha conocido 10s procedimientos para obtener informaci6n de
esquema mediante controladores OLE DB y consultando tablas especificas de SQL
Programacidn de bases de datos con Visual Basic .NET
Server y Oracle. Los dem6s RDBMS cuentan con mecanismos similares, no tene-
mos m6s que consultar la documentaci6n de referencia y localizar las tablas, vistas
o procedimientos almacenados que entregan esa informaci6n de esquema.
Component
OdbcCommand
OleDbCommand
IDbCommand
Figura 8.1. Las clases Command de cada proveedor implementan 10s miembros
de la interfaz IDbCommand
-~
c
Si creamos un comando mediante el m6todo Createcommand ( ), segun acaba
de decirse, la asociaci6n entre comando y conexi6n ya se habrA establecido automi-
ticamente. Createcommand ( ) no toma par6metro alguno, por lo que el comando
en si deberd establecerse posteriormente, mediante las propiedades CommandT ype
y CommandText tratadas m6s adelante.
I D b C o m m a n d Cornando = C o n r ~ O l e D b . C r e a t e C o m r n a n d( )
En el capitulo previo, con el fin de crear un lector de datos, vimos c6mo cre6ba-
mos un comando directamente con el constructor de una de las clases Command,
concretamente con 01eDbCommand. Dicho constructor acepta un 01e Db Conne c-
ti on como segundo partimetro, asociando el comando con la conexi6n. L6gicamen-
te, 6sta deber6 haberse creado previamente.
Otra posibilidad es que creemos el comando sin facilitar ese segundo parfimetro,
s610 con el texto del comando a ejecutar:
En este caso, antes de llamar a ninguno de 10s metodos de ejecucibn, habria que
asignar la conexion a la propiedad Connection. Tambien podemos leer esta
propiedad, a1 obtener un comando, para asi poder acceder a 10s parfimetros de la
conexi6n. Dicha propiedad es de tipo IDbConnection en la interfaz IDbCommand,
per0 en la implementaci6n de cada proveedor el tip0 es el exclusivo de ese provee-
dor por lo que, en la prfictica, no podriamos asignar a la propiedad Connection
de un comando una conexi6n de tip0 distinto.
an
Una vez tenemos el comando preparado, podemos ejecutarlo recurriendo a uno
de 10s tres m6todos con que cuenta IDbCommand o bien a algun m6todo especifico
del proveedor que estemos utilizando.
8. Recuperacidn de datos
-1
- I
I
I
--
-hi
/
-( IDa t a R e c o r d
IDa t a R e a d e r
\
I
SqlDataReader
Imports System.Data.OleDb
Module Module1
Sub M a i n (
~ u e s t r a T a b l a("Editoriales")
MuestraTabla("Llbr0s")
End Sub
D i m Ltct ~ ) As
r 0let)bDat~aReader = Cornando. ExecuteReader ( )
Dim I n d i i P As Byte
Fo
Next
Con5ole.WriteLine(vbCrLf & New String("=", 6 0 ) )
Console.WriteLine0
End While
End Module
Imports Systern.Data.SqlC1ient
Module Module1
Sub Main( )
, 1.2 -. -~' if.
Dim Conexion As N e w SqlConnection( -
"Data Source=inspiron; Initial Catalog=Libros; " &
"User ID=sa; Password=" )
co
I J - , , ( a n r I n _ i
Dim Lector As SqlDataReader = Comando.ExecuteReader()
Dim Indice As B y t e
Pvogramacidn de bases de datos con Visual Basic .NET
Do
r
Fo nt - 1
Lector.Close ( ) '
Conexion.CSose ( ) '
End Sub
End Module
Observe que, salvo la conexi6n y ejecuci6n del comando, la mayor parte del c6-
digo se encuentra en el interior del bucle Do/Loop While L e c t o r . NextResult ( ) .
Asi procesaremos 10s tres conjuntos de datos obtenidos. Dentro de &te tenemos
otro bucle, el equivalente a1 del ejemplo anterior, para recorrer todas las filas de ca-
da conjunto. El resultado, como se aprecia en la figura 8.4, es prdcticamente i d h -
tico. A diferencia del programa anterior, sin embargo, tan s610 hemos conectado
con el origen una vez y tan s610 hemos ejecutado un comando.
S
~
~ ~ ~ ~
Suponga que desea obtener el titulo de cada uno de 10s libros que hay en la ta-
bla L i b r o s , junto con el nombre de su editorial y el precio. Estos datos podria uti-
lizarlos para generar un informe impreso, un documento HTML o cualquier otro
tip0 de resultado.
En el c6digo siguiente nos limitamos a mostrarlos por consola, per0 el proceso
seria btisicamente el mismo.
Module Module1
Sub Main( )
2 1
Cone 0 ' ,~
~ ..
t i I
I
.
,
A?
, r f i + I \I
Wh
C o n s o 1 e . W r i t e i L e c t o r . G e t St r 1 nq ( 0 . P a d R i g h t (50) L vbTab)
C o n s o 1 e .W r i t e i L e c t o r . Get S t r i rlg ( 1 . P a d R i g h t ( 2 5 ) L vbTab)
C o n so 1 e .W r i t eL 1 ne f " { 0 ,5 1 ' I , Lect o .GetDouble(2)
End While
L e c t r L .Close ( ) '
End Sub
End Module
I
Figura 8.5. Resultado de la consulta SQL sobre el documento Excel
8. Recuperacidn de datos
Al acceder a Excel, el proveedor deduce el tip0 de 10s datos a partir del con-
tenido de las celdillas, como se indico anteriormente. Por eso el precio se trata
como un Double. Al conectar con un origen distinto podria tener que cambiar
G e t D o u b l e ( ) pOr G e t D e c i m a l ( ) .
Nota
Suponga que quiere crear una consulta de libros pertenecientes a una cierta
editorial, permitiendo a1 usuario que sea 151 quien seleccione dicha editorial. Asu-
miendo que utilizaremos la base de datos creada anteriormente en Oracle, el c6-
digo necesario seria el siguiente:
Imports Systern.Data.OracleC1ient
Module Module1
Sub Main()
I L-Fj,-jy,la tjs s p l s;.r\--;.r
.js ,:c;I,,Jzld,-) a I;, j:>,s-J .f-. ,>'a
D i m NurnEditorial As Integer
.,
1 :;:~lj:i tc:;:-;s +i ~ I .
::jilL:,3 ,G+= ? , : i ~ r ~ ? r i ~~i: >
l - J I .!.t~i,-j~rjk
Console.Write ("Introduzca un c6digo de editorial : " 1
NumEditorial = Integer.Parse(Console.ReadLine0)
.i?P=:
L' i i n t~5L-
Cornando.Parameters.Add(New Oracleparameter( -
"CodEditorial", NumEditorial) )
' Z -
( , I 2 / . 77
I "
i' + , -> c1 I- + / > +
Whlle Lector.Read0
Console.WriteLine (Lector("1SBN") & vbTab & Lector("Tltu1o") )
End While
End Module
el c6digo necesario para mostrar el c6digo y nombre de cada una de ellas, facili-
tando asi la selecci6n.
e un solo valor
Hasta ahora hemos usado reiteradamente el metodo ExecuteReader ( ) para
acceder a uno o varios conjuntos de datos. En ocasiones, el resultado de una sen-
tencia de consulta ser6 dnico, por ejemplo una suma, contador o algdn otro cdcu-
lo. En casos asi, aunque podriamos utilizar ExecuteReader ( 1, resulta m6s fdcil
y eficiente utilizar el m6todo ExecuteScalar ( ) . h e devuelve directamente el
resultado, sin necesidad de recorrer filas ni columnas.
Partiendo del ejemplo del punto anterior, modifique la consulta dej6ndola asi:
Comando.CornrnandText = "SELECT COUNT(*) FROM Libros " L -
"WHERE Editorial=:CodEditorial"
atos
Aunque el titulo de este capitulo hace referencia expresa a la recuperaci6n de
datos, y a este tema se dedica la mayor parte del mismo, hay que apuntar que un
Prograrnacidn de bases de datos con Visual Basic .NET
Module Module1
Sub Main ( 1
rA
Dim Conexion As New OleDbConnection( ~
Cone 0
I '.' , :
Cornando.CornrnandText = "INSERT INTO [LibrosSI " & -
"VALUES ( 1 6 , '1-893115-50-X', & -
" ' Wi re 1 e s s Java ' , ' Jonathan Kriuds en ' , 3, 3 4 . 9 5 ) 'I
1 i,i , r i - 1
Dim Resultado As Integer = Comando.ExecuteNonQuery()
End Module
Para ver el resultado puede ejecutar alguno de 10s ejemplos previos, recuperan-
do el contenido del documento y mostrhdolo por la consola, o bien abrir directa-
mente el documento en Microsoft Excel para observar el cambio.
Otras operaciones
Dado que con un comando podemos ejecutar cualquier sentencia SQL sobre el
origen de datos, podemos virtualmente extraer y manipular todo su contenido.
8. Recuperacidn de datos
Module Module1
Sub Main( )
, I *-
D i m Conexion As New SqlConnection( -
"Data Source=inspiron; Initial Catalog=Libros; " & -
"User ID=sa; Password=")
' 1 + 3 1 -
D i m Comando As SqlCommand
3 2 - 3 - j
=
< _ = c cx -
Conexion.CreateCornrnand()
D i m Indice As Byte
Programacidn de bases de datos con Visual Basic .NET
Console .Wr 1 t e L 1 ne ( " { 0 ,-2 0 } " & vbTab & "{1,-50]" &
vbTab & " { 2 , 5 ) " , Lector("Nombre")
Lector ("Titulo"), Lector ("Precio"
End While
Lector.Close0 '
Conexion.Close( )
End Sub
End Module
Como puede ver, la sentencia SQL asignada a CommandText bien podria ser la
de consulta a una tabla llamada LibrosEditorial. Sabemos, sin embargo, que
tal tabla no existe, puesto que 10s datos de las editoriales y 10s libros se encuentran
separados. LibrosEditorial es una vista que, a1 ejecutarse, devuelve la lista de
datos que puede verse en la figura 8.7.
/'I
Figura 8.7. Conjunto de datos devuelto por la vista L i b r o s E d i t o r l a l
Ejecutar un procedimiento almacenado es, si cabe, m6s f6cil que abrir una vis-
ta. B6sicamente tenemos que dar tres pasos, asumiendo que tenemos la conexi6n
ya preparada:
8. Recuperacidn d e datos
Dim I n d i c e As Byte
While Lector.Read ( 1
implementaciones especificas para cada proveedor, 10s conjuntos de datos tan s6-
lo cuentan con una clase: D a t a S e t . En esta clase pueden existir, segun se apunta-
ba en el quinto capitulo, multiples tablas, con sus filas y columnas, restricciones y
relaciones.
Un conjunto de datos puede obtenerse a partir de un origen de datos, mediante
un adaptador, o bien definirse mediante c6digo. Independientemente de esto, el
contenido del conjunto de datos puede almacenarse y recuperarse localmente, exis-
tiendo tambien, como es 16gic0, la posibilidad de resolver 10s cambios con el ori-
gen de datos del que se extrajo la informaci6n.
Si bien en principio no existen clases derivadas de D a t a S e t, nada nos impide
crearlas a fin de que se ajusten a la estructura concreta de 10s conjuntos de datos
sobre 10s que vamos a operar. Estas clases, derivadas de D a t a S e t , serian conjun-
tos de datos con comprobaci6n de tipos que facilitarian el acceso a 10s datos com-
probando, a1 tiempo, que Gstos Sean de 10s tipos apropiados. Aunque podriamos
crear estas clases manualmente, Visual Studio .NET dispone de asistentes que se
ocupan de hacerlo. Los conocerb en un capitulo posterior, a1 tratar las herramien-
tas del entorno para el trabajo con datos.
En este capitulo utilizaremos siempre conjuntos de datos genericos, es decir,
objetos de la clase D a t a S e t .
Tablas y relaciones
Las dos propiedades fundamentales de un D a t a S e t son T a b l e s y R e l a t i o n s .
Cada una de ellas mantiene una referencia a una colecci6n de objetos, en el primer
caso de la clase D a t a T a b l e y en el segundo de D a t a R e l a t i o n . La primera es
importante ya que nos permite recuperar y modificar la informaci6n almacenada
en el conjunto de datos, mientras que la segunda define la relaci6n entre tablas en
caso de que el conjunto est4 compuesto por varias.
Cuando se llena un D a t a S e t a partir de un origen de datos, mediante un adap-
tador, las colecciones de tablas y relaciones se definen autombticamente. Nada nos
impide, sin embargo, afiadir nuevos elementos a las colecciones, es decir, crear
nuevas tablas y relaciones en el interior del D a t a S e t . Es algo que veremos en la
prbctica posteriormente.
Cada tabla se compone, como ya sabe, de filas y columnas, representadas por
las colecciones Rows y Columns, respectivamente, de la clase D a t a T a b l e . Me-
diante la colecci6n Rows podemos acceder a 10s datos que contienen las filas,
mientras que con la coleccion Columns tenemos a nuestro alcance la informaci6n
de esquema de cada columna: nombre, tipo, etc. La tabla tambien puede contar
con una colecci6n de objetos C o n s t r a i n t especificando las restricciones aplica-
bles a 10s datos.
Mediante objetos D a t a R e l a t i o n , alojados en la propiedad R e l a t i o n s , se
establecen 10s enlaces entre las tablas que forman parte del D a t a S e t . Estas, a1
igual que el contenido del resto del D a t a S e t , pueden recuperarse mediante un
adaptador de datos o bien definirse con c6digo.
Programacidn de bases de dafos con Visual Basic .NET
Seleccih de datos
Mediante la propiedad Rows de cualquier D a t a T a b l e es posible acceder a la
totalidad de las filas que componen la tabla en ese momento. Utilizando el mgtodo
S e l e c t ( ) de la clase D a t a T a b l e , no obstante, es posible establecer filtros de se-
lecci6n para recuperar un arreglo compuesto tan s610 por aquellas filas que 10s
cumplen.
Observe que el metodo S e l e c t ( ) no afecta a la propiedad Rows, es decir, no
provoca que en la colecci6n aparezcan o desaparezcan filas, sin0 que es el mismo
metodo el que devuelve un arreglo de objetos DataRow con el resultado.
A1 efectuar busquedas con el m6todo S e l e c t ( ) ,por defecto, no se distingue en-
tre mayusculas y minusculas. Este comportamiento est6 controlado por la propie-
dad C a s e s e n s i t i v e del D a t a S e t que, por defecto, tiene el valor F a l s e . Puede
asignarle T r u e si necesita que a1 establecer un filtro se distinga entre mayusculas y
minusculas.
Aunque, como se veri mis adelante en este capitulo, es posible almacenar y re-
cuperar conjuntos de datos usando archivos locales, al trabajar con objetos D a t a S e t
asociados a origenes de datos, que es el caso m6s habitual, resultan imprescindi-
bles 10s adaptadores de datos, introducidos tambien en el quinto capitulo. Un
adaptador de datos actua como intermediario entre el origen de datos, con depen-
dencias de cada product0 particular, y el D a t a S e t , que tiene una estructura total-
mente independiente.
9. Conjuntos de datos
/
-elo
IDbDa t a Adap t e r
Una vez que tenemos el adaptador preparado, con su comando de selecci6n de-
finido, para ejecutarlo y obtener 10s datos en el DataSet no tenemos m6s que in-
vocar a1 metodo Fill ( ) . Este puede tomar distintas listas de par6metros, aunque
la sintaxis m6s habitual es la siguiente:
AdaF)tadorDatos.F i l l ( C o n j u n t o O a t o s 1
Valor Comentario
Valor Comentario
Component 1
I I I
OdbcCommandBuilder
I
OleDbCommandBuilder
I OracleCommandBuilder
SqlCommandBuilder
Puede ver c6mo funciona un objeto CommandBuilder con un ejemplo tan sim-
ple como el siguiente, en el cual se crea un SqlCommandBuilder a partir de un
adaptador de datos ya existente. Una vez creado, podemos utilizar 10s m6todos
antes citados para acceder a 10s comandos y obtener las sentencias SQL. El resulta-
do de la ejecuci6n seria el de la figura 9.3. Cambie de proveedor y ver6 c6mo las
sentencias se ajustan, en consecuencia, a la sintaxis del nuevo origen de datos.
I m p o r t s System. Data. S q l C l i e n t
Module Module1
Sub Main( )
End Sub
End Module
DataAdapter
Connection
InsertCommand
Updatecommand
Debe tener en cuenta que el metodo Update ( ) del adaptador se sirve del es-
tad0 de cada DataRow de la tabla para determinar si necesita 0 no ser actua-
lizada. No debe llamar al metodo Acceptchanges ( ) del DataSet antes de
invocar a Update ( ) , ya que, de hacerlo, todos 10s RowState volverian a su
estado por defect0 y el adaptador no encontraria nada que actualizar. Tras Ila-
mar a Update ( ) , a fin de mantener sincronizado el DataSet, puede llamar
a Acceptchanges 0 bien volver a invocar al metodo Fill ( ) a fin de ver no
solo 10s cambios propios sin0 tambien 10s de terceros.
Recuperacion de datos
Utilizando el proveedor S q l c l i e n t , para acceder a SQL Server, vamos a pre-
parar un adaptador que nos devuelva en un DataSet las tablas E d i t o r i a l e s y
L i b r o s que hay en la base de datos. Recuperaremos las tablas por separado, con
dos sentencias independientes, obteniendo asi varios conjuntos de datos segtin se
vio a1 tratar 10s DataReader. En este caso, sin embargo, no tendremos que pasar
explicitamente de un conjunto a otro y leer las filas de manera individual, sin0 que
obtendremos toda la informaci6n de una vez.
Creado el adaptador de datos y el propio DataSet, nos limitamos a llamar a1
metodo F i l l para ejecutar 10s comandos y recuperar la informaci6n de esquema y
datos propiamente dichos. El resto del programa, como puede verse a continuaci6n'
es una sucesion de bucles con 10s que recorremos todas las columnas de cada fila
de cada tabla que contenga el Da t aS e t .
Imports System.Data.SqlClient
Module Module1
Sub Main( )
x-
Dim Adaptador As New SylDataAdapter( -
"SELECT * FROM Editoriales; SELECT * FROM Libros",
"Data Source=inspiron; Initial Catalog=Libros; " &
"Uscr l D = s a ; Fasswoid-")
Adaptador.Fi11 (Datos)
Con sol e . Write Li ne ( "Tab1 a ' " & Tabla. Tab l e N a m e & " '")
E n d Sub
E n d Module
I I
Observe que en este caso hemos facilitado como segundo parametro del meto-
do Fill ( ) el nombre que deseamos dar a 10s DataTable. Otra opcidn seria aria-
dir un elemento a la colecci6n TableMappings de cada adaptador, indicando el
nombre de la tabla origen, que suele ser Table si en la sentencia SQL no se ha esta-
blecido ninguno, y el nombre que deseamos dar a1 DataTable.En cualquier caso,
a1 ejecutar el programa tras estos cambios el resultado sera practicamente identi-
co, tan s610 diferiran 10s nombres de 10s DataTable existentes en el DataSet.
A , ? a p t a \ j r ) r .F i l l S c t l e m a ( D a t a S e t , S c h e r n a T y p e , NombreTabla
D i m C o n e x i o n As New SqlConnpction ( -
"Data Sour(-t=inspiron; I r l i t i a l Catalog=Libros; " &
"IJCcr ID=sa; Pa-sword=")
D i m A i a p t a d r F d i t c r i a l e s As New SqlDataAdapteri
"SELEPT * FROM E d i t o r i a l P s " , C o n e x i o n )
Dim A d a p t a d o r L i b r o s As New S y l D a t a A d a p t e r i
"SELECT * FROM L i b r o s " , C i r l e x i o n )
A J , p t a ~ o r E d i t o r i a l e s .F i l l S c h ~ r n a(
D2t J s , S c h e m a T y p e . S o u r c e , " E d i t o r i a l e s " )
A ? a y t a d o r L i b r r > s .F i l l S c h e m a ( D a t o s ,
S i hemaTyye. S o u r c e , " L i b r o q " )
..
D a t o s . R e l a t i o r i s . A d d (New D a t a R e l a t i o n ( " F K - E d L i b r o " , -
Datos.Tables ( " E d i t o r i a l e s " ) . C o l u m n s ( " I D E d i t o r i a l " ) ,
Datos.Tables("Libros"). C o l u m n s ("Editorial")) )
9. Conjuntos de datos
Tras las dos llamadas a Fillschema ( ) , observe c6mo se afiade la relaci6n en-
tre las tablas creando un objeto DataRelation. Facilitamos a su constructor el
nombre que deseamos darle a la relacion, una referencia a la columna de la tabla
principal y otra a la columna de la tabla de detalle. Con esto se generan automiti-
camente las restricciones apropiadas. A1 ejecutar el codigo anterior, tendremos un
DataSet sin datos per0 con toda la informaci6n de esquema. Podemos mostrar
6sta por consola con el codigo siguiente, que producirs el resultado mostrado en la
figura 9.6. Observe 10s atributos de las columnas IDEditorial e IDLibro, asi
como las restricciones definidas en cada tabla.
Dim I d k > l a As D a t a T a b l e , R e s t r i c c i i n As C o n - t r a i n t
{ "Nombre", Columna.Columr~Ndme},-
{"Tip"", C o l u m n a . D a t a T y p e . T o S t r i r , ~ ( )1 , -
{ "Admite nulo", Columna.AllowDBNull}, -
{ "Autoincremento", Columna .AutoIilcrement 1 , -
,-15]..: {l]", -
DatosColumnas (Contador, O i , -
DatosColurnnas (Contador, 1 ))
Fo C o n s tr a i n t s
CType(Restriccior1, F o r e i g n K e y C o n s t r a i n t ) . C o l u m n s (01,
CType(Restriccior1, -
F o r e i g n K e y C o n s t r a i n t ) . R e l a t e d C o l u r n n s ( 0 )1
Else
Console.WriteLine("Valor l i n i c o : {O)", -
C T y p e ( R e s t r i c c i o r 1 , UniqueConstraint).Columns(O))
Programacidn de bases de datos con V i s u a l Basic .NET
Debe tener en cuenta que, una vez se han definido las restricciones, el orden
en el que invoque a 10s metodos Fill ( ) de cada adaptador es importante. Si
tras las dos llamadas a Fillschema ( ) del ejemplo anterior intenta ejecutar
la sentencia AdaptadorLibros. Fill (Datos, "Libros"), Veria que se
produce una excepcion. Esto es asi porque, al no haber todavia datos en la ta-
blade editoriales, 10s libros estan haciendo referencia a editoriales que no exis-
ten, violando una de las restricciones.
Imports System.Data.SqlClient
Sub Main I )
r pe ~ ).:
-- ,.,>1,,,,.;5
7 Lind :<;n??>
lL5i1 L-t.;:nLjil
i I
1-
riales.RowUpdated, -
New SqlRowUpdatedEventHandler(Address0f ActualizaEdltorlales)
I" i
I -
- 1 -1 -.,' I . '
Dim Datos As New DataSet ("MisDatos")
1 1 t 1
s.FillSchernai -
.Source , " Ed itoria 1es " )
lScherna(Datos, -
SchemaType. Source, "Libros" )
f ,. ' .i
Da tos .Re 1at io ns .Add (New DataRe 1at io n ( " FK-EdL ib ro " , -
Datos .Tables ("Editoriales") .Columns ("IDEditorial"), -
Datos.Tables ("Libros").Columns ("Editorial")) )
+_
1 3
1
Dim Filas As DataRowCollection = -
Datos.Tables ("Editoriales").Rows
9. Conjuntos de datos
Fi
w York" 1 )
AdaptadorEditoriales.Update(Datos, "Editoriales"]
IDEditorial, 60.5))
I i
.I I , 5 I + 1 2 L L L '
ctualizaEditoriales( ~
If args.StaternentT
-_
IDEditorial = New SqlCommand ("SELECT @@IDENTITY", -
args.Cornrnand.Connection1.Executescalar ( )
t i
Ademas del metodo Find ( ) , que se emplea para encontrar la fila que tiene un
cierto valor en la columna que actua como clave principal, tambien puede usar
el metodo Select ( ) para recuperartodas aquellasfilasque cumplen un cierto
criterio de busqueda. Consulte la informacion de referencia de la clase Data-
Table para ver las diferentes versiones que existen de dicho metodo y saber
como se usa.
Di aSet ("Hospital")
IL.
W i t h Pacientes .Columns
Type.GetType("System. Int32") )
.AutoIncrement = True
.AutoIncrementSeed = 1
.AutoIncrementStep = 1
.Readonly = True
W i t h .Add("Nombre", Type.GetType("System.Stririg") )
.MaxLength = 40
.AllowDBNull = False
End W i t h
W i t h .Add ( " Dire ccion", Type. Ge tT ype ( "System. St r i rig" ) )
.MaxLength = 50
End W i t h
W i t h .Add ( "Tel e fono", Type. GetType ( "System. String" ) )
.MaxLength = 12
End W i t h
End W i t h
, L I-
1-
" Type.GetType("System.Int32") )
.AutoIncrementSeed = 100
.AutoIncrementStep = 5
.Readonly = True
End W i t h
x
.Add("Paciente", Type.GetType("System.Int32") )
.Add("Fecha", Type.GetType ("System.DateTirne"))
W i t h .Add("Descripcion", Type.GetType ("System.String"))
.MaxLength = 1024
.AllowDBNull = False
End W i t h
End W i t h
, .,
I
,ji f . ., . - .
,*..Lil.iii,C'L;
.
i.7
.
::i.t:,-e c,r;iQrL?
Historial.PrimaryKey = New Datacolumn() -
[Historial.Columns ("IDEntrada"))
Programacidn de bases de datos con V i s u a l Basic .NET
E a c i e r i t ~ s . C o l u m n (s " I D P a c i e n t e " ] ,
H i r t i r i a l . c o l u m r ~ s( " P a c - i e r l t e " ) ) )
Dim E r t t r a d a As D a t a R o w = H i s t o r i a l . N e w K o w ( )
C n t r a d a ("Paciente") = Paciente ( " I D P a c i e n t e " )
Erltrada ("Fecha")
F r l t r a ?a ( " Des c r I p ) = " ( ' ~ l i c o renal"
Hlst. r i a l . RI ds . A d A ( E n t r a d a )
I'acierlte = Pdcientes.NewKow( )
1 e r A t e( " N ~ ~ r n b r e " )
" F i l i ~ ~ i Fr i~r l ~o "~ ,
" ) = " P e r , 12"
P,icier,te("Telefor,r~r")= " 1 2 3 4 5 6 789''
P a c i e n t e s . ROWF. A d d ( P a c i e r L t e )
r
t
_ _ I --
Independientemente de c6mo se haya creado la informacion de esquema del
D a t a S e t , y facilitado el contenido de las tablas que lo componen, el metodo para
obtener esa informacion y contenido son 10s mismos que ya conocemos. Para verlo
en la practica, vamos a aiiadir a1 programa compuesto por 10s dos bloques de c6di-
go previos, introducidos en el metodo Main ( ) , dos metodos adicionales. El pri-
mero, a1 que llamaremos InformacionEsquema ( ) , recibe como parimetro una
referencia a un D a t a S e t y muestra por la consola su estructura. El c6digo de este
metodo, muy similar a1 usado en un ejemplo anterior, seria el mostrado aqui:
Sub I r t f o r m a c l o n E s q u e m a (ByVal D a t o s As D a t a S e t )
Prograrnacidn de bases de datos con Visual Basic .NET
Fo
C o n s ~ l e . W r i t e L i n e ( " * * ~ *COLUMNAS
* *****'I )
co ,-15)..: {l)", -
DatosColumnas (Contador, 0 ), -
DatosColumnas (Contador, 1) )
Ne
Console.WrlteLlne(New String("=", 6 0 ))
Next
f r, ~ t C + : I
bla.
mos el segundo parimetro, el archivo contendria s610 10s datos como puede apre-
ciarse en la figura 9.9.
A1 recuperar el archivo de datos, mediante el metodo ReadXml ( ) ,tambien ten-
driamos que indicar si queremos leer la informaci6n de esquema o s610 10s datos.
Figura 9.8. Podemos usar Visual Studio .NET para obtener una representacion
del esquerna
DiffCrams
A medida que se efectuan cambios en las tablas de un Data s e t, las colecciones
DataRow de cada DataTable alojan no s610 la nueva informaci6n, sin0 tambien el
estado y 10s datos que contenian previamente. Esta informaci6n, relativa a 10s cam-
bios producidos desde que se cre6 o recuper6 el contenido del D a t a S e t , perma-
nece ahi hasta que se llama a1 m6todoAcceptChanges ( ) del D a t a S e t que, como
sabe, invoca a1 metodo homdnimo de cada DataTable.
Cuando se almacena la informaci6n en un archivo XML, mediante el metodo
W r i t e x m l ( ) , lo que se almacena son 10s valores actuales de las filas, tras efectuar
todos 10s cambios, a pesar de que no se haya invocado a A c c e p t c h a n g e s ( ) . A1
recuperar el archivo, por tanto, tendriamos un Data s e t con datos per0 sin infor-
maci6n de c6mo se oper6 sobre estos. La perdida del estado de las filas, y la infor-
maci6n previa a la modificacibn, no seri importante si la aplicaci6n esti diseiiada
para trabajar siempre localmente.
9. Conjuntos de datos
.-. .............
f .\\Ek400\SiitansC\
._ .... r--;,.gt;;s >"' ..v'-F--.
. . . . . . . . . . . . "_\C?: ...............................
Figura 9.9. Estructura del archivo XML conteniendo solo 10s datos, sin informacion
de esquema
Suponga, por el contrario, que la aplicaci6n que esth disefiando obtiene el es-
quema y 10s datos a partir de una conexi6n con un origen de datos. A partir de ahi,
sin embargo, tiene que trabajar sin conexi6n porque el programa, pongamos pol
caso, se ejecuta en un portitil y el usuario viaja de un punto a otro sin posibilidad
de conexi6n permanente con el servidor de datos.
Todas las ediciones, por lo tanto, deberhn almacenarse localmente a fin de quc
puedan posteriormente, en alg6n momento en que se tenga conexibn, resolverse
con el origen de datos.
En un caso asi es imprescindible conservar no s610 10s datos nuevos, sin0 1:
propia informacih de 10s cambios que han ido efectuindose. Estos pueden alma.
cenarse en un documento XML con formato DiffGrarn, una estructura en la que sc
determina el estado de cada fila y, ademis, se indica cud1 era el estado anterior i
Prograrnacio'n de bases de datos con Visual Basic .NET
10s cambios y 10s posibles errores que pudieran haber surgido. En este caso habria
que facilitar a1 mktodo Wri texml ( ) , como segundo parbmetro, el indicador Xml-
WriteMode.DiffGram.
Puede efectuar una prueba, partiendo del c6digo del ejemplo anterior, a fin de
ver la estructura del DiffGvarn.
Dk 10s pasos siguientes:
0 Despuks de aiiadir 10s dos pacientes a la tabla paciente, invoque a1 mkto-
do Acceptchanges ( ) del DataSet. De esta forma 10s cambios quedarbn
consolidados y las filas no mantendrbn estado ni valores previos.
0 Modifique el telkfono del segundo de 10s pacientes, simplemente por modi-
ficar un dato que ya estaba aceptado para ver c6mo lo refleja el DiffGrarn.
Puede hacerlo con una sentencia como la siguiente:
P a c i e n t e s . S e l e c t ( " N o m b r e = ' F i l i p i n o Fino"') ( 0 )( " T e l e f o n o " ) =
0 Llame a1 final del ddigo, tras aiiadir las entradas del historial del segundo
paciente, a1 mktodo Wri teXml ( ) pasando el indicador XmlWriteMode .
Di f fGram como segundo parbmetro.
0 Haga doble clic sobre el archivo generado para abrirlo en Internet Explorer
y poder apreciar, como en la figura 9.10, la descripci6n del estado y datos
del DataSet.
Observe que el primer paciente y la entrada que hay en su historial no cuentan
con la propiedad haschanges, ya que tras introducirlos en el DataSet se llam6 a
Acceptchanges ( ) . En las dem6s entradas podemos apreciar el estado modi f ied
o inserted.
Fijese en la parte inferior del documento, en la rama <diffgr: before>. Alli
encontramos 10s valores que tenia la segunda fila de la tabla Pacientes antes de
efectuar el cambio indicado mbs arriba. Aqui aparecerian, de igual forma, 10s con-
tenidos de las filas que pudieran haberse eliminado.
Fijese en c6mo se identifica de manera inequivoca cada fila de cada tabla con un
entero asignado a la propiedad roworder.El numero de fila del paciente modifi-
cad0 coincide en la rama de datos y en la de valores previos, como puede verse.
Programacidn de bases de datos con Visual Basic .NET
Identifieador Cornentarlo
Como puede ver, ReadXml ( ) siempre puede obtener el esquema, si 4ste se en-
cuentra embebido en el documento XML, o bien deducirlo a partir de la estructura
de 10s datos. La Onica excepci6n se produce cuando va a recuperarse un DiffGram,
ya que 4ste no incorpora el esquema en el documento y tampoco es posible dedu-
cirlo a partir de 10s datos. Si vamos a recuperar un documento de tip0 DffGrarn,
por tanto, es imprescindible que antes hayamos obtenido el esquema con una lla-
mada a ReadXmlSchema ( ) .
En el ejemplo desarrollado antes, en el que se definia un Data Se t y se aiiadian
datos a dos tablas, aiiada las sentencias siguientes a1 final:
Datos.WriteXrnlSchema i"EsquernaHospital.xsd")
D a t o s . W r i t e X r n 1 ("Hospital.rm1")
Datos.WriteXml("HospitalCor~Esquema.xrnl", X r n 1 W r i t e M o d e . W r i t e S c h e r n a )
Datos .WriteXml ("HnspitalCarnbios.xml", X r n l W r i t e M o d e . D i f f G r a m )
De esta forma tendrd cuatro archivos diferentes con informacih del DataSet:
0 EsquemaHospital . xsd:Tendri el esquema XML, sin datos.
0 Hospital. xml: Contendri 10s datos actuales, sin esquema y sin informa-
ci6n de modificaciones.
0 HospitalConEsquema. xml: Almacenard el esquema junto con 10s datos.
0 HospitalCambios .xml: Contendrfi el DiffGrarn con 10s datos y modifica-
ciones, sin informacidn de esquema.
9. Conjuntos de datos
Sub M a i n ( )
Datos.Rea HospitalCarnbios.xm1")
I n f o r m a c i o n E s q u e r n a ( Datos)
M u e s t r a C o n t e n i d o (Datos)
End Sub
De esta forma, a1 ejecutar cualquiera de las variaciones veria si las filas mantie-
nen su estado 0, por el contrario, lo han perdido. En la parte inferior de la figura 9.11
puede ver c6mo se indica que la segunda fila de la tabla Pacientes est6 modifi-
cada, y las dos ultimas de la tabla His torial son nuevas. Estos datos no 10s veria
Prograrnacidn de bases de datos con Visual Basic .NET
usando el entorno de Visual Studio .NET como tendri ocasi6n de ver en capitulos
posteriores.
Imports S 7 s t ii rn . Da t a . S '3 1 T 1 i i: rl t
Module M o d u l e 1
Sub Ma1 1 1 ( )
MuestraFilas ( -
"Titulos d e l a e d i t o r i a l 1 o r d e n a d o s p o r p r e c i o " , Fllas)
End Sub
su
.
C o n s o 1e W r 1 t e L i n e (
" [ 0 ,- 50 ) ( 1,6) ( 2 , 3) ' I , ~
End Module
MarshalByValueComponent
IBindingList
Funcionamiento de un DataView
Los objetos DataView se asocian con objetos DataTable, ya sea facilitando la
referencia a este ultimo a1 constructor de la clase DataView o usando la propie-
dad Table del DataView para vincularlo a1 DataTable. En cualquier caso, a
partir de ese momento podemos usar la propiedad Item del DataView para ac-
ceder a las filas de la vista, que ser4n todas o parte de las existentes en la tabla.
Cada uno de 10s elementos de la propiedad I tem, que actua como indexadora de
la clase, es un objeto de la clase DataRowView. Los objetos de esta clase ofrecen
una vista de un DataRow en un estado en particular, es decir, no mantienen 10s di-
versos estados que puede tener una fila de datos durante la edici6n.
El conjunto de filas que forman la vista dependerii del valor que tenga la pro-
piedad RowFil t er. gste puede facilitarse como segundo partimetro del construc-
tor de DataView o bien establecerse posteriormente mediante una asignaci6n a
dicha propiedad. El filtro se define como una cadena de caracteres en cuyo interior
se introducen 10s pariimetros de seleccibn, con la misma sintaxis empleada con el
metodo Select ( ) de la clase DataTable.
Si no deseamos que las filas aparezcan en la vista con el orden por defecto, no
tenemos m4s que indicar en la propiedad Sort el nombre de la columna o colum-
nas por las que deben ordenarse. Esa columna se convertir4 en clave de un indice,
facilitando las operaciones de busqueda. Opcionalmente, puede indicar tras cada
nombre de columna si el orden debe ser ascendente o descendente. Esta cadena,
indicando las columnas por las que se ordenari, tambibn puede facilitarse como
pariimetro a1 constructor de Da t aVi ew, concretamente como tercer argumento.
Por ultimo, en lo que respecta a las propiedades de selecci6n de filas, podemos
asignar un estado a ROWS t a t e Fi 1t e r a fin de obtener s610 las filas que se encuen-
tren en el estado indicado. Como se decia antes, 10s objetos DataRowView repre-
sentan el valor de un DataRow en un cierto estado, por defecto el valor actual,
pudiendose indicar otro estado diferente mediante una asignaci6n a RowState-
Filter o entregando el mismo valor como ultimo argumento del constructor.
Adem4s de acceder a 10s datos, mediante la citada propiedad I t e m , tambien
podemos efectuar operaciones de edici6n sobre las filas, utilizando para ello 10s
metodos AddNew ( ) y Delete ( ) del DataView y BeginEdit ( ) , EndEdit ( ) y
CancelEdit ( ) de cada DataRowView. Que estas operaciones Sean posibles, o
no, dependerii de 10s valores que mantengan las propiedades A11owNew, A 1 1ow-
Delete y AllowEdit del propio Dataview.
Programacidn de bases de datos con Visual Basic .NET
Todos 10s DataTable cuentan con una vista por defecto, a la que puede acce-
derse mediante la propiedad Defaultview,que puede modificarse mediante
las propiedades RowFilter, Sort y RowState. De esta forma podriamos
modificar la vista por defecto que nos ofrece el propio DataTable, en lugar
de crear un DataView nuevo.
Funcionamiento de un DataViewManager
A diferencia de Da t aVi ew, 10s objetos Da t aVi ewManage r se enlazan directa-
mente con un DataSet y no con un DataTable. Su finalidad es facilitar una vista
global de todas las tablas que forman el conjunto de datos, respetando las relacio-
nes que pudieran existir entre ellas. Podemos vincular el DataViewManager con
el DataSet facilitando una referencia a este ultimo a1 constructor del primero, o
bien sirviendonos de la propiedad DataSet con que cuenta la clase Dataview-
Manager.
En lugar de crear un nuevo DataViewManager, tambien podemos obtener el
que tiene por defecto el conjunto de datos mediante la propiedad Defaultview-
Manager de la clase DataSet.
Los dos miembros de m5s inter& para nosotros, en la clase DataViewManager,
serdn Dataviewsettings y CreateDataView ( ) . El primero, una propiedad,
nos permite acceder a la colecci6n de objetos DataViewSet ting que establecen
las propiedades de la vista de cada tabla, mientras que el segundo, un metodo, es
el encargado de crear nuevas vistas asociadas a tablas.
Cada elemento de Ia colecci6n DataViewSet tings mantiene 10s atributos de
la vista aplicada a cada tabla. Para ello, la clase Dataviewsettings cuenta con
las mismas propiedades RowFilter, Sort y RowStateFilter explicadas en el
punto anterior, junto con la propiedad Table que vincula la configuraci6n con
una cierta tabla.
10. Relaciones y vistas
___
Sub I 4 a i n ( )
Di ect i o n ! -
., . , itial C a t a l i
" U S C . ~ID=sa; E'asswcxd=" )
D i m AdaptddorLibros AS New S q l D a t a A d a p t e L (
" S E L E C T A FROM L i b r o s " , CIr l e x i b r l ,
D i m VistaTotal A s New -
DataView(Datos.Tahlrr ("Libras"))
D i m V i r t a E r o g r a r a c i o n A s New ~
DataView(Dator.Tdblesi"llbros"), -
" T i t u l c L I K E ' P r o g r a r n a c i o r l * "I, "Titulo",
DataViewRowState.CurrentRows)
Programacio'n de bases de datos con Visual Basic .NET
, >
DataViewRowState.CurrentRowsi
I '
* - I 1 1
,c
f , J i i
Cada DataTable cuenta con una vista por defecto, un objeto DataView a1 que
hace referencia la propiedad Def aultview. Esta vista, inicialmente, hace referen-
cia a todas las filas de la tabla. Utilizando las propiedades RowFilter, Sort y
Rows t ate Fi1te r, sin embargo, podemos configurarla para que nos facilite 10s
datos que nos interesen en cada momento.
10. Relaciones y vistas
0 C:\P&MVisualBasicNmCap_lO\VariasVistas\bin\VariasVistas.ere -10
Figura 10.3. Conjuntos de filas ofrecidos por las distintas vistas creadas
Sub Main( j
I :, , __
- ...~
L i ~ i . i i . L.A,2 ~ . : c : ~ c . ~ i ~ ~ ~ :
~ i. il,,~
r r
I r ~ L - L t i 1 i _,
Dim MiTabla As DataTable = Datos.Tables("Libros")
L - -- i L -
MiTabla.DefaultView.RowFi1ter = ~
Wi
. RowFilter = "Editorial=l"
. S o r t = "Precio DESC" '
.RowStateFilter = DataViewRowState.Currer1tRows
End With
Imports S y s t e m . D a t a . S q l C l i e n t
Module M o d u l e 1
Sub M a i r J ( )
-
D i m C o n e x i o n As New S q l C o n n e c t i o n ( -
"Data Source=inspiron; I n i t i a l Catalog=Libros; " & -
"U s er I D= s a ; Pas s w o r d = " )
D i m A d a p t a d o r L i b r o s As New S q l D a t a A d a p t e r (
"SELECT * FROM L i b r o s " , C o n e x i o n )
r . t -
D i m D a t o s As New D a t a S e t ("MisDatos")
D i m M i T a b l a As D a t a T a b l e = Datos.Tables("Libros")
D i m Columna As DataColumn
D i m NornbreColumna As String
D i m ValorBuscado As String
MiTabla.DefaultView.S3rt = NombreCclumna
. ?
Fo
End Sub
End Module
Cualquier modificaci6n de las filas causari que en el DataTable del que depen-
de la vista se aiiadan nuevas filas o cambie el estado de 10s asistentes. En cualquier
caso, esos cambios no son en firme hasta en tanto no se llame a1 metodo Accept-
Changed ( ) del DataSet 0,en caso de que deseemos transferirlos a un origen de
datos, se utilice el metodo Update ( ) del adaptador de datos.
Manteniendo el metodo Mue s tr a Fi1as ( ) de 10s ejemplos previos, cambie el
metodo Main ( ) para que quede tal y como se muestra a continuaci6n:
Sub Main( )
r 7 1 i * I i
7 . t z * + 4 , 1 iP # ? , >
I c +
2 . i
Fila.EndEdit ( ) '
AdaptadorLibros.Update(Datos.Tables("Libros")
End Sub
Figura 10.5. La vista de datos antes y despues de aiiadir una nueva fila
.t-
I T
AdaptadorEditoria1es.MissingSchemaAction =
M i s s i n g Sc h e ma Ac t i on . A d d W 1 t h Ke y
AdaptadorLibros.MissingSchemaActior1 = -
Mi s s i ng SchemaAc t i o rl .Add Wi t h Ke y
,
Dato?.Relations.Add(New -
DataRelation ("Libros d e l a editorial", ~
Con esto, las editoriales tan sdlo deberian mostrar 10s libros cuyo titulo comen-
zase con 10s caracteres P rog rama cion A1 ejecutar el programa, sin embargo,
I'
veri que el resultado es exactamente el mismo que obtenia antes. Con la sentencia
10. Relaciones y vistas
DataGrid1.DataSource = Datos.Tables("Editoriales"].DefaultView
-.__-_______-.__ ~
ultimedia Telemaco. 43
EdificioValreaiW,l'phnta
901 Grsiscn Street
605 Thtrd Avenue New Ywk
Ante todo, tenga en cuenta que este libro se centra en el tema del acceso a datos
desde Visual Basic .NET usando principalmente ADO.NET, por lo que no se apor-
ta un estudio detallado de XML como el que podria encontrar en un titulo m i s es-
pecifico sobre este tema. Tambikn puede encontrar abundante informaci6n sobre
XMLen http://MSDN.Microsoft.com/xml.
El entorno de Visual Studio .NET cuenta con diseiiadores y asistentes que fa-
cilitan la mayoria de las tareas que implica el trabajo con XML, como la edici6n de
10s documentos, creaci6n de esquemas XSD u hojas de estilo XSL. Algunas de es-
.
tas herramientas las conoci6 en el tercer capitulo, a1 crear 10s archivos Libros xsd
y Libros .x m l .
</Libras>
<Libras>
<IDLibro>G</IDLibro>
<ISBN>84-415-1351-l</ISBN>
<TItulo>Prograrnacihn con Visual Basic .NET</TItulo>
<Autor>Francisco Charte</Autor>
<Editorial>l</Editorial>
<Precio>39</Precio>
</Libras>
<Editoriales>
<IDEditorial>l</IDEditorial>
<Nornbre>Anaya Multirnedia</Nornbre>
< Di reccio n > J u a n Ign a c i o Luc a d e Ten a, 15< / D i re c c i on>
</Editoriales>
<Editoriales>
<IDEditorial>2</IDEditorial>
<Nombre>McGraw-Hill</Nornbre>
< Di recci on > Ed i f i c i o Va 1re a 1t y , 1 a p 1ant a < / Di re cc ioTi>
</Editoriales>
</Libras>
The Extensible Markup Language (XML) is the unlversal format for structured documents and data on the Web \\ML
en f 0
nuinrs explains XML briefly The base specifications are XML 1 0, W3C RecommendationFeb '98, and Nariieswaces.Jan
'99 The .,ML Activitv Stateniwt explains the W3Cs work on this topic in more detail For related work, see
Nearby XML Protocol XML Schema XML Querf XLink, Wointei, XML Base DOM PDF CSS YSL XHTML
~ _
MathML SMlL _ Sianature and Canonicalization
XML
Working Drafts
Follow the links above for details about the drafts issued by the XML Query. XML Schema, and XML Linlang WGs The
documents listed below are the working drafts issued by the YML Core working group
..
XML /nc/usims j%/nziudel Last Call working dmtt issued16 May2001
reauirernents section of original proposal
worlang group XML Core
.lSSUeS
feedback 1mwxmLxinclude Lornrnents
i i h K information Ss! Proposed Recommendationissued 10 August 2001
. feedback ~-xI*il-infoset-cornrnents
discussion e v cornw textxml
%MLFraamenl lnterchanas Candidate Recommendationas of 12 February2001
Los documentos XML deben estar bien formados y ser viilidos. Un documento
est6 bien formado si todas las marcas de apertura cuentan con sus respectivas mar-
cas de cierre, todos 10s atributos se introducen entre comillas dobles y el documen-
to cuenta con un solo elemento raiz en el que estan incluidos todos 10s demas. El
fragment0 anterior, por ejemplo, es un documento bien formado, por lo que un
analizador XML podria leerlo y extraer datos sin mayores problemas. fistas son
normas del propio lenguaje XML y que, por tanto, debe cumplir cualquier docu-
mento XML.
Que un documento XML sea o no viilido dependerii, primero, de que este bien
formado y, segundo, que su estructura concuerde con la definida en una DTD o es-
quema XSD. Estos elementos, las DTD y 10s esquemas XSD, se utilizan para vali-
dar documentos XML y verificar que son apropiados para la aplicaci6n que debe
procesarlos.
Esta definici6n puede colocarse a1 inicio del propio documento XML o bien al-
macenarse separadamente, en un archivo con extensi6n d t d , haciendose referen-
cia a el desde el documento XML mediante la marca < ! DOCTYPE>.El inconveniente
de las DTD es que no siguen la sintaxis propia de XML y no son demasiado flexi-
bles, por ejemplo a1 no contar con tipos de datos mas especificos ya que en #PCDATA
entra cualquier secuencia de caracteres, sin importar cuiiles Sean ni su longitud.
11. X M L
Visual Studio .NET, a1 producir nuevos documentos XML, emplea por defect0
el U R L h t t p : / / t e m p u r i . o r g asociado a 10s ambitos con nombre. Este URL
debe modificarse por uno que identifique de manera unica a ese Ambito, gene-
ralmente con el nombre de dominio de nuestra empresa y algun identificador
adicional, dando lugar a un URI unico.
A pesar de que 10s documentos XML, y 10s esquemas XSD, son relativamente
fdciles de comprender y pueden ser editados manualmente, incluso con herramien-
tas tan sencillas como el Bloc de notas de Windows, lo cierto es que estin pensados
para que Sean aplicaciones a medida las que 10s manipulen. Estas aplicaciones
podrian, ya que son archivos de texto simples, leerlos e intentar analizarlos por si
mismas, per0 no es necesario gracias a la existencia de estandares como DOM y
SAX.
SAX, como su propio nombre indica, es un conjunto simple de funciones que
facilitan la extracci6n de datos a partir de un documento XML generando eventos
a medida que lo lee, de tal forma que la aplicacibn, en cierta forma, es participe del
analisis del documento. DOM es una alternativa m i s compleja, si bien tambidn
mas flexible, que recupera un documento completo y nos ofrece la posibilidad de
navegar por sus nodos, leyendo y modificando informacion. Para ello, a partir de
la informacih leida del documento se genera un irbol jerirquico con todos 10s
elementos.
En Visual Basic .NET, afortunadamente, no tenemos por qu6 utilizar mdtodos
de relativo bajo nivel para operar sobre documentos XML, aunque realmente nada
nos impide hacerlo. Por una parte disponemos de la clase X m l R e a d e r que, de
11. X M L
Desde Visual Basic .NET puede utilizar XSLT a traves de la clase XslTrans-
form,aplicando una hoja de estilo XSL a cualquier documento XML que tenga alo-
jado en un XmlDocument, o derivado, para el que exista un XPathNavigator.
Svstem .Xml.Schema
XmlSchema XmlSerializer
II Svstem.Xml
XmlDocumen t XmlElement
XmlDataDocument XmlNode
XmlReade r XmlWri ter
XslTransfo m
XPathNavigator
II Microsoft.Xml.XPath I
Figura 11.2. Ambitos relacionados con XML y algunas de sus clases
proveedores ADO.NET, si bien sus metodos y propiedades son otros. Este metodo
para acceder a un documento XML seria similar a1 us0 de SAX, per0 en lugar de
responder a eventos que se generan a medida que se encuentran 10s diversos ele-
mentos, como ocurre con SAX, disponemos de un cursor solo de lectura y unidirec-
cional, so10 puede avanzar, para recuperar esos elementos.
En la figura 11.3 puede ver la clase XmlReader y sus derivadas, asi como la
interfaz que implementan dos de ellas y cuyo objetivo es facilitar informacion de
posicih de 10s elementos en el documento. XmlTextReader es el medio mds
rdpido para leer un documento XML, a1 no efectuarse validacion alguna respecto a
una DTD o esquema XSD. Estas funciones si las tiene XmlValidatingReader.
Object
41 XmlReader
XmlTextReader t
IXmlLineInfo
XmlValidatingReader
XmlNodeReader
Imports S y a t e r n . X m 1
22. X M L
Module Module1
Sub M a i n ( )
D i m L e c t c r As New XmlTextReader("Libros.xrn1")
While L e c t c r . h e a d ( )
End Select
End While
Li L.C1 ?
End Sub
End Module
IC:\P&lctVisuatBasicN~Cap-l I\LecturaXMLWn\kturaXML.exe ri
Las clases derivadas de XmlReader est6n dirigidas, tal como indica su propio
nombre, a la lectura de informacibn, per0 en ningdn caso facilitan mecanismos
11. X M L
X P a thNa vig a b 1 e
XmlDocument
XmlDataDocument
Module Module1
s New XmlDocurnent [ )
Dim Nodo As XrnlNode '
I' I
D o c u m e n t o . L o a d ("libros.xml" 1
Titulo = Nodo.ChildNodes(2).InnerText
Precio = Nodo.ChildNodesi5).InnerText
l l r 5 i -> 12r51"r
Nodo.ChildNodes(5).InnerText = Precio
End If
Next
1 I_ I
End Module
Dim R e s u l t a d o As X P a t h N n d e I t e r a t o r = ~
teLi CrL f , Re c u 1t a d o . C o u n t 1
While R e ; u l t a d o . M c v e N e X t i )
Con sole . Writ e L i r ~ ie" i 0 J " , Rei 1 1 1t 41,.
C u r r e r l t . Va 1ue )
End While
End Sub
End Module
__ __ -I_^_ __- - - --
Las dos primeras lineas son las que identifican a1 documento como una planti-
lla XSLT u hoja de estilo XSL. Todas las instrucciones XSLT van precedidas con el
prefijo xsl, como puede apreciarse. La marca <template> aplica la plantilla que
hay a continuaci6n, hasta la etiqueta de cierre </template>,a todos 10s datos del
documento, ya que la expresi6n XPath del atributo match selecciona todo su con-
tenido. A continuaci6n encontramos marcas HTML corrientes para la creaci6n de
una tabla. La etiqueta <for-each> es equivalente a un bucle For/Next de Visual
Basic, repitiendose tantas veces como elementos Libro existan en la rama Li-
bros. Ya sabe que esta expresion puede cambiarla para seleccionar cualquier otro
conjunto de datos, por ejemplo 10s titulos de una cierta editorial, segun se vio an-
tes. Finalmente, en el interior de las celdillas de la tabla HTML se introduce el va-
lor de dos elementos de cada libro, leidos con <value-of>.
Aunque podriamos asociar esta plantilla de transformacibn directamente a1
documento XML, viendo el resultado en Internet Explorer dado que este es capaz
de analizar y ejecutar la transformacibn, lo que nos interesa es ver como podemos
hacerlo desde un programa propio. El unico elemento adicional que precisamos,
aparte de 10s que ya conocemos, es la clase XslTransform. Esta deriva directa-
mente de O b j ect y no implementa interfaz alguna. El metodo de mayor inter& es
Trans form ( ) ,encargado de aplicar la transformaci6n a1 documento. Previamen-
te, sin embargo, es precis0 recuperar la plantilla XSLT mediante el metodo Load ( ) ,
equivalente a1 hom6nimo de la clase Xml D o cument.
Prograrnacidn de bases de datos con Visual Basic .NET
I m p o r t s Sy: tern.X r r l
I m p o r t s Sq'tem.Yrnl.YPath
I m p o r t s -;> tpm.Jm1.x 1
End Module
Las clases que acabamos de conocer tienen utilidad por si mismas, ya que ha-
cen posible la lectura y manipulaci6n de documentos XML desde cualquier aplica-
ci6n desarrollada con Visual Basic .NET, sin importar su finalidad. Muchas de las
operaciones descritas, no obstante, encuentran su mayor aplicaci6n en nuestro ca-
so, centrados en el tema de acceso a datos, a1 sincronizar un documento XML con
un DataSet o viceversa.
Suponga que ha creado un DataSet,mediante 10s adaptadores de datos adecua-
dos, y tras tener 10s DataTable con las filas de datos quiere obtener s610 aquellas
que cumplan una cierta condicibn, o bien generar una pdgina HTML a partir del
11. X M L
I ; , Burqueda Fa,
IL---------
LItO ~ ___- - ~~~ 1____
HPC
_ _ _ ~
Figura 11.9. Documento HTML generado a partir de la transformacion XSLT
Segun se aprecia en la figura 11.5, Xml DataDo cument es una clase derivada de
XmlDocument por lo que, en principio, ya contamos con todos 10s miembros de
&a y sabemos, bfisicamente, como recuperar un documento XML y recorrerlo. A
10s miembros heredados, XmlDataDocument afiade un propiedad, DataSet, y
algunos metodos, como GetElementFromRow ( ) o GetRowFromElement ( ) , que
facilitan la obtencion de un elemento XML perteneciente a una cierta fila del Da-
taset o viceversa. El constructor de la clase tambien puede tomar como parfimetro
un Data S et, crefindose la vinculacion entre conjunto de datos y documento XML
de manera inmediata.
Programacidn de bases de datos con V i s u a l Basic .NET
Vamos a ver 10s dos procedimientos con un breve ejemplo en 10s dos puntos si-
guientes.
I m p o r t s Systern.Xm1
I m p o r t s System.Data
Module Module1
Sub M a i n ( )
D a t o s . R e a d X r n l S c h e m a ["Lihros.xsd")
D i m Docurnento As New X r n l D a t a D o c u r n e n t i D a t o s )
.r
Datos. E n f o r c e C o n s t r a i n t s = False
11. XML
D i m Tabla As DataTable
D i m F i l a As DataRow, c o l u r n n a As D a t a C o l u r n n
End Sub
End Module
-~
Este proceso es acin mfis simple si cabe, ya que basta con crear el XmlData-
Document vinculado a1 DataSet,entregando este como argument0 a1 constructor
del primero, para tener autom6ticamente el documento XML que representa a1
contenido del conjunto de datos. LPara que puede servirnos esto? Como se decia
antes, podemos efectuar seleccionados de datos XPath sobre un DataSet, o apli-
car una transformacih a 10s datos para generar un nuevo documento. Son posibi-
lidades que ha conocido brevemente en puntos anteriores.
Programacidn de bases de datos con Visual Basic .NET
Imports System.Xm1
Imports System.Xml.XPath
Imports System. Data
Imports System.Data.SqlC1ient
Module Module1
Sub Main()
' Jr!il;il;lG.,: li;!a
.
cznl;.XIL7li
I
D i m Conexion As N e w SqlConnection( -
"Data Source=inspiron; Initial Catalog=Libros; " & -
"User ID=sa; Password=")
j,, ..., l , , L % s .
I ,-.I._i- ,- :
1 p3t_.s::.it
D i m Datos As N e w DataSet("MisDatos")
11. X M L
Di ~
[ E j i t o r i d 1= 1 ] / T 1t ul o " 1
E n d While
E n d Sub
E n d Module
remoto. En casos asi el conjunto de datos se convierte en XML para ser transmitido
por la red, invirtihdose el proceso en el destino.
Como probablemente sabr6, Visual Basic .NET es un product0 que puede ad-
quirirse por separado en su propia caja, y en cualquier comercio especializado, o
12. Capacidades d e d a t o s en V i s u a l S t u d i o .NET
bien como parte de una suscripcion a alguna de las ediciones de Visual Studio .NET,
que es lo m & habitual. A pesar de corresponder todos 10s productos a una misma
version, la primera de Visual Studio .NET presentada en febrero de 2002, existen
varias ediciones distintas. Todas ellas comparten un mismo entorno, la plataforma
.NET y la misma biblioteca de clases, per0 difieren en ciertas caracteristicas como
10s servidores integrados en el paquete o la funcionalidad de ciertos elementos de
diseiio. Visual Basic .NET, como lenguaje, podemos encontrarlo en una de las edi-
ciones siguientes:
Visual Basic .NET Standard: Es la edicion m6s simple y unica que puede ad-
quirirse sin una suscripcion de servicio. Incluye el entorno de Visual Studio
.NET per0 solo con 10s diseiiadores y elementos de Visual Basic .NET.
Visual Studio .NET Professional: Aparte de Visual Basic .NET, tambikn inclu-
ye 10s lenguajes Visual C# .NET, Visual C++ .NET y Visual J# .NET, asi como
capacidades inexistentes en la edicion anterior: Crystal Reports, herramien-
tas visuales de bases de datos, herramientas de diseiio para el servidor que
facilitan el acceso a servicios, bases de datos, etc. Puede obtenerse una ver-
sion de prueba de esta edicion, limitada a 60 dias, solicitiindola en la Web de
Microsoft.
Visual Studio .NET Enterprise Developer: Seguramente la edicion m6s apro-
piada para el desarrollo de aplicaciones con necesidades de acceso a bases
de datos, ya que incorpora todas las herramientas de diseiio necesarias y al-
gunos servidores fundamentales, como SQL Server, donde la anterior solo
facilita MSDE. Tambikn se diferencia de la anterior en la incorporation de
Visual Sourcesafe, Visual Studio Analyzer y Application Center Test.
Visual Studio .NET Enterprise Architect: Es la edicion superior del producto,
en la que, aparte de todo lo indicado en la anterior, encontraremos una ver-
sion especifica de Visio para el modelado de bases de datos y aplicaciones y
el producto Microsoft BizTalk Server para la construccion de procesos de in-
tegracion con aplicaciones de clientes, proveedores o socios.
Puede encontrar una comparativa completa entre las tres ediciones de Visual
Studio .NET, asi como enlaces a comparativas individuales entre Visual Studio
.NET y las ediciones Standard de 10s lenguajes, en http: //msdn.micro-
soft.com/vstudio/howtobuy/choosing.asp.
Programacidn de bases de datos con Visual Basic .NET
MlCmsofr
Visual
Standard
Basicnet
Algunas ediciones de Visual Studio .NET ofrecen, aparte del propio entorno de
diseiio, 10s compiladores y la plataforma .NET, otros productos que podriamos
necesitar para el desarrollo, comprobaci6n y depuraci6n de nuestros proyectos.
En el campo que nos interesa especialmente, el de tratamiento de datos, esos pro-
ductos son MSDE, Microsoft SQL Server 2000 y Microsoft Visio.
Con la edici6n m6s baja, la Professional, disponemos de MSDE que, como se in-
dic6 en su momento, es, bisicamente, el motor de SQL Server per0 sin herramien-
tas de administraci6n y capacidades reducidas en cuanto a numero de conexiones
y tamafio de las bases de datos. El us0 de MSDE, respecto a productos como Mi-
crosoft Access, es que estaremos empleando el controlador S qlC1i e n t y todas las
posibilidades de SQL Server, aunque con MSDE. Evolucionar, cuando las necesi-
dades lo requieran, a SQL Server ser6 mucho m i s ficil.
Las ediciones Enteprise, tanto Developer como Architect, vienen acompaiiadas de
varios servidores de Microsoft, entre ellos SQL Server 2000. La licencia del produc-
to nos permite utilizarlo durante el desarrollo y comprobaci6n, no en explotaci6n.
En cualquier caso, es una buena posibilidad ya que podemos operar sobre uno de
10s RDBMS mds potentes y populares.
Finalmente, la edici6n Enterprise Architect tambien se entrega junto a la edici6n
hom6nima de Microsoft Visio, un product0 que nos permitird usar tecnicas de mo-
delado basadas en est6ndares para construir nuestros modelos de bases de datos y
negocio.
insplron pubs.dbo2
+ 0 DEPT
0 EDITORIALES
0 EMp
0 LIBROS
0 RECEIPT
+ 0 SALGRADE
+ r
b Sinonimos
ntos almacenados
E# Caias de mensajes
UContadores de rendmiento
a RegistTas de eventor
- - ___ ___
- @W a d w & serndores 1 f f Cuadro dc heiramtentas
Dependiendo de la edici6n de Visual Studio .NET con que contemos, las capaci-
dades de estas herramientas visuales serin unas u otras. Resumidamente podria-
mos decir que:
0 En las ediciones Standard podemos explorar las conexiones para ver el con-
tenido de las tablas de bases de datos Access y MSDE.
0 La edici6n Professional tambien nos permite explorar servidores SQL Server
y cualquier origen con un controlador ODCB u OLE DB, asi como diseiiar ta-
blas y vistas sobre MSDE.
0 Las dos ediciones Enterprise permiten explorar cualquier servidor para el
que exista un controlador OLE DB u ODBC, asi como SQL Server de forma
nativa. Tambien facilitan el diseiio de tablas, procedimientos almacenados,
vistas, desencadenadores y, en general, cualquier elemento que pueda exis-
tir en un RDBMS como SQL Server u Oracle.
12. Capacidades de datos e n V i s u a l Studio .NET
I
Asumiendo que estamos trabajando con una de las ediciones Enterprise de Vi-
sual Studio .NET, en 10s capitulos siguientes se abordard el us0 de las herramien-
tas visuales de datos y muchos de 10s componentes que pueden vincularse con un
D a t a S e t, D a t a V i e w 0 similar para facilitar la presentaci6n y manipulacih por
parte del usuario final. Los puntos siguientes le ofrecen una visi6n general de 10s
temas que podri encontrar en dichos capitulos:
Us0 del Explorador de servidores para definir una conexi6n y acceder a 10s
elementos de un origen de datos.
Diseiio, desde el Explorador de servidores, de nuevos elementos tales como
tablas, vistas y procedimientos almacenados, observando el resultado desde
el propio entorno de Visual Studio .NET sin necesidad de recurrir a la herra-
mienta de administracidn propia de cada producto.
Generaci6n automatica de conexiones a origen de datos, adaptadores de da-
tos y objetos D a t a S e t con comprobaci6n estricta de tipos.
Us0 de 10s diversos asistentes de Visual Studio .NET para la generacih
semi-automAtica de comandos SQL para la creaci6n y modificacih de con-
sultas, vistas, procedimientos almacenados, etc.
Vinculaci6n de conjuntos de datos y vistas con componentes de interfaz
Windows y Web.
Diseiio de formularios de visualizaci6n y edicidn de datos tanto para inter-
faces basadas en Windows como para clientes Web, introduciendo el us0 del
Asistente para formularios de datos.
A medida que vaya conociendo todos 10s elementos, veri c6mo una parte impor-
tante del c6digo que en 10s ejemplos de capitulos previos introduciamos manual-
mente, por ejemplo para definir una conexibn, un adaptador de datos o un conjunto
Prograrnacidn de bases de datos con Visual Basic .NET
de datos, ahora se genera de forma automQtica,de tal forma que tan s610 tenemos
que usar 10s componentes creados mediante operaciones de arrastrar y soltar.
esurnen
Con este breve capitulo se han situado, en cuanto a caracteristicas de acceso a
datos se refiere, las diferentes capacidades de las ediciones existentes de Visual
Studio .NET. Ahora ya sabe lo que podr6 hacer, o no, segun la edicidn que tenga
instalada en su sistema.
Tambien se han avanzado, en una visidn rQpida, algunos de 10s temas que se
van a tratar en 10s capitulos de esta tercera parte del libro, a partir del capitulo si-
guiente.
En 10s ejemplos desarrollados en 10s capitulos de la segunda parte hemos conec-
tad0 con diferentes origenes de datos, recuperado informaci6n mediante objetos
DataReader, ejecutado comandos, llenado DataSe t con informaci6n de esos ori-
genes a traves de adaptadores de datos, generado automAticamente 10s comandos
de actualizacibn, etc. Todas esas acciones las hemos implementado escribiendo c6-
digo, lo cual nos ha servido para conocer muchos de 10s detalles de las clases im-
plicadas, sabiendo c6mo emplearlas sin necesidad de asistentes ni un entorno de
disefio.
No obstante, ese entorno de disefio existe en Visual Studio .NET, y podemos
aprovecharlo con el fin de ahorrar una cantidad importante de trabajo, producien-
do automiiticamente, mediante operaciones de arrastrar y soltar, 10s componentes
que son necesarios para comunicarse con un origen de datos, extraer y devolver
informaci6n.
El objetivo de este capitulo es mostrarle c6mo puede servirse de esas herramien-
tas de disefio para efectuar tareas como la edici6n directa de datos, definici6n de
estructuras y otros elementos, creaci6n automiitica de componentes de conexibn,
adaptadores y conjuntos de datos, etc.
Tal y como podrii observar, el contenido de este capitulo es mucho menos te6-
rico que el de 10s capitulos de la segunda parte y va a indicarle directamente c6mo
efectuar cada tarea, por lo que es casi imprescindible que se encuentre delante de
su ordenador con Visual Studio .NET abierto para poder ir siguiendo las explica-
ciones.
Prograrnacidn de bases de datos con Visual Basic .NET
vinculo de datos, mostrado en la figura 13.3, que ya conoce por haberlo usado en
capitulos previos, concretamente a1 tratar 10s archivos UDL. Seleccione el provee-
dor OLE DB que desea utilizar e introduzca 10s datos necesarios para identificar el
origen de datos y facilitar cualquier parimetro adicional que pudiera necesitarse.
onemnes de datos
e mensaws
+ izJ Contadares de rendmiento
+ @j
Regirbos de eientos
f % Servlclor
+ I. Serviuos de Crystal
+ ‘1 Seriidores SQL Serler
---- - -
Usando el menu emergente asociado a una conexion, tras crearla, podra tanto
modificar sus parametros como eliminarla, en caso de que ya no le sirva.
Programacidn de bases de datos con Visual Basic .NET
Figura 13.4. Al desplegar la conexion aparece una lista de carpetas con objetos
existentes en el origen de datos
r@ Conemones de dabs
+ f* LlbrOS.SC0Tr
0 Servidwes
as de base de datos
dmentor almacenados
Figura 13.6. Acceso desde Visual Studio .NET a un servidor SQL Server que se ejecuta
en otra maquina
~ I - I - ~
L-.-_^_( ~ - ~ ~
~ l _ ~ l _ _ ( ~ l _ _ _ ” l _ ” . ~ - ~ ~ ” . - l _ l l _ _ .
nexi6n mediante OLE DB, es necesario establecer una conexi6n. Esta se abre, nor-
malmente, de forma automdtica cuando es necesario, por ejemplo a1 ir a acceder a
las tablas de una base de datos. Dependiendo de las operaciones que efectuemos,
esa conexi6n se mantendr6 abierta durante mds o menos tiempo.
iC6mo saber si una cierta conexi6n est6 o no abierta? Tan s610 tiene que fijarse
en el icono que precede a1 nombre de la conexibn, o la base de datos en caso de SQL
Server. Si dicho icono tiene en la parte inferior derecha un pequeiio enchufe es que
hay abierta una conexi6n. En caso de que lo que aparezca sea una cruz en rojo, no
hay conexi6n activa. En la figura 13.7 puede observar, ampliado, un detalle de di-
cho icono, con una conexi6n activa, a la izquierda, y cerrada, a la derecha.
Para cerrar una conexi6n explicitamente, cuando le interese, no tiene mds que
abrir el menu emergente de la conexi6n y seleccionar la opci6n Cerrar conexion.
La integraci6n de Visual Studio .NET con SQL Server es superior a la que tiene
con el resto de origenes de datos, existiendo opciones especificas para este RDBMS
que nos estdn disponibles para 10s demas. Una de esas opciones es la que nos per-
mite crear una nueva base de datos desde el propio Visual Studio .NET, sin nece-
sidad de recurrir a1 Administrador corporativo. Puede hacerse de dos maneras:
1. Seleccionando la opci6n Crear nueva base de datos SQL Server del menu
emergente asociado a1 elemento Conexiones de datos, en la ventana Explo-
rador de servidores.
2. Seleccionando la opci6n Nueva base de datos del menu emergente asociado
a una instancia de servidor de SQL Server, como se aprecia en la figura 13.8.
Conexiones de dams
+ a dimenson
- Inrpron
+ hlf Colas de mensajer
Contadores de rendimiento
Reqissos de evenbs
+ f* Serviaos de Crvstal
- 19 Seruidorer SQl Server
+ a
IB Propedades
Figura 13.8. Opcion para crear una nueva base de datos SQL Server
la carpeta Tablas de la base de datos que prefiera, una tabla cualquiera, haciendo
doble clic sobre ella. Si el origen de datos no es SQL Server primer0 tendri que de-
finir una conexih, s e g ~ n 10s pasos explicados antes, tras lo cual el proceso seria
idhtico.
Tras hacer doble clic, y siempre que la conexi6n con el origen sea satisfactoria,
veri aparecer en el entorno de Visual Studio .NET una cuadricula con 10s datos ac-
tuales de la tabla, siendo posible la eliminacihn, modificaci6n e insercidn de datos.
En la figura 13.9 puede ver como se editan dos tablas de manera simultinea. La de
la parte superior corresponde a una base de datos de ejemplo instalada con Oracle
8i, mientras que la inferior es la tabla L i b r o s que creamos con Microsoft Excel en
10s ejemplos del tercer capitulo. En ambos casos se ha definido una conexion me-
diante el proveedor OLE DB.
+ $VStaS
t @ Procedimientor aimacenado
- +
)biibroi5cm
hagramas de bare de datw
I1
I
I X
+ 0 BONUS 10.75
+ c ] D m 10.71
+ EDIIORIKES 39
+ n
- €MP .10
+ LlBRO 39
+ LlBROS 10.75
+ 0 RECEIPT 10 52
37.24
10.52
21.04
10.52
1U,52
24,04
.10
Observe que siempre que defina una conexion utilizando el proveedor Microsoft
JET, por ejemplo para acceder al libro de Excel en este caso, en el Explorador
de servidores siempre aparece el prefijo ACCESS. Si se fija, no obstante, Vera
que el nombre del archivo es L i b r o s . x l s y no L i b r o s . m d b .
13. Herramientas visuales de datos
~._____II_
x l__ ~ l _ . __..____-....
- ~ ---I.____.____._-.-..-.---- -
A1 abrir una tabla con el sistema anterior, haciendo doble clic sobre ella, obten-
dremos todo el contenido, lo cual puede significar tan s610 unas decenas de filas,
como ocurre con la base de datos creada a mod0 de ejemplo para este libro, o bien
miles de ellas, en caso de que conectemos con una base de datos en explotaci6n
real u obtenida como copia de una que se encuentre en explotacih.
Usando las habituales teclas de desplazamiento del cursor, o bien el puntero
del rat6n para actuar sobre la barra de desplazamiento, nos podremos desplazar
de un punto a otro fila a fila. Tambikn pueden emplearse ciertas combinaciones,
como Control-Inicio y Control-Fin, para ir ripidamente a la primera de las filas o a
la ultima, respectivamente.
Para insertar una nueva fila no tenemos mAs que desplazarnos debajo de la u1-
tima que tiene datos, apareciendo automiticamente una fila vacia en la que pode-
mos introducir 10s nuevos datos. De forma similar, podemos modificar el contenido
de cualquiera de las filas mostradas. Si deseamos eliminar una de ellas tendremos
que seleccionarla completa, haciendo clic en el selector que aparece a la izquierda
de la primera columna, y pulsar a continuacion la tecla Supr.
Debe tener en cuenta que ciertas columnas de datos pueden no ser editables.
No podra, por ejemplo, modificar la columna I D L i b r o de la tabla L i b r o s de
la base de datos SQL Server, puesto que su valor se genera automaticamente.
Si aiiade una nueva fila, el valor de dicha columna sera insertado automatica-
mente. Tampoco podra editar aquellas columnas cuya precision exceda unos
ciertos limites.
A1 abrir una tabla, como hemos hecho en el punto previo, no s610 aparece una
cuadricula con las filas y columnas de datos sin0 que, ademis, se activa una paleta
de herramientas que por defect0 no esti visible. En ella, segun puede verse en la fi-
gura 13.11, existen multiples botones con 10s que podemos ocultar y mostrar dis-
tintos paneles, ejecutar una sentencia SQL, afiadir otras tablas, agrupar datos, etc.
Prograrnacidn de bases de datos con Visual Basic .NET
Simplemente situe el punter0 del rat6n sobre cada b o t h para obtener una indica-
ci6n de su finalidad.
1x
_ __
k a ~QI -
-.__- gavharbpo- ! %L '_ ~ EZ a
Figura 13.11. Paleta de botones activa durante la edicion de datos
I)
,%to
que pulsar el b o t h Ejecutar consulta. En la figura 13.14 puede ver el Panel de dia-
grama, en la parte superior; el Panel SQL, en el drea central, y el Panel de resulta-
dos en la secci6n inferior. Ldgicamente, puede afiadir a la consulta SQL cl6usulas
de selecci6n de filas, ordenacibn, agrupamiento, etc.
Otra forma de establecer criterios de selecci6n y ordenaci6n consiste en abrir el
Panel de cuadricula (segundo de 10s botones de la barra) e introducir directamente
las opciones deseadas. En la figura 13.15 se ve c6mo se ha asignado a la columna
N o m b r e de la tabla Editoriales el alias Editorial, titulo que aparece en el pa-
nel de resultados. Ademds se ha ordenado ascendentemente por el titulo del libro,
aparte de seleccionarse s61o aquellos cuyo precio esti por debajo de 10s 40 euros.
l@
I
Nota
lReaa lEditmd
; 1 8 484415 1202 27
4 1 5 1132 Guia paiaca w r a usuanos de Excel 2002
Gum pacbca para uwanos de Kdix
10.52
10,52
10,52
h y a Mulhmedla
Anaya Mulbmedia
Anaya Mulbrnedra
,I 84415 1290 6 Guia pacbca para uwarios de Visual Baac NET 10 75 Anaya Mulbmedia
;I 84415 12914 Guia pacbca para uylanos de Visual f b d i o NEI 10.52 Anaya Mulbmeh
uj 84415 13244 Gua pactlca para uwarios JBulder 7 10 75 Anaya Mulbmedia
84415 1145-4 Inmducoon a la pogramaoon 24,04 Anaya Mulbmeda
84415 1230 2 Manual atanzado Excel 2002 21,04 Anaya Mulbmeha
84415 1261 2 Progtamwon con Delphi 6 y Kylh 37,Z Anaya Mulbmedia
84415 1351 1 Programanon CM Visual Baa< NET 39 Anaya Mulbmedia
84415-13924 Progiamaaon imr Visual C; NET 39 Anaya Mdbmedia
84415 1136 5 SQLferier 2000 10,75 Anaya Mulbmedia
1893115 94 1 User Interface k s g n for Programmers 31 np-ess
A1 abrir una tabla desde Visual Studio .NET, haciendo doble clic sobre ella en el
Explorador de servidores, se genera automiticamente una sentencia SQL de con-
sulta para recuperar todas las filas y columnas de la tabla. Con 10s elementos in-
dicados en el punto previo, 10s distintos paneles inicialmente ocultos, es posible
seleccionar columnas y filas. La sentencia, no obstante, seguir5 siendo de consulta.
Si tras abrir una tabla despliega la lista adjunta a1 b o t h Cambiar tipo, como se
ha hecho en la figura 13.16, podri cambiar la sentencia SQL para que en vez de ser
de consulta sea de inserci6n de resultados, de valores, de actualizacidn o de eli-
minaci6n. Segun la opci6n que elija, en el Panel SQL veri aparecer una sentencia
I N S E R T INTO, UPDATE 0 DELETE.
A partir del momento en que se modifique el tip0 de sentencia, las acciones que
llevemos a cab0 en 10s paneles de diagrama y cuadricula, eligiendo columnas o
estableciendo criterios de selecci6n de filas, se aplicarin a la nueva sentencia SQL.
Puede hacer pruebas manteniendo abierto el Panel SQL para ver las sentencias ge-
Programacidn de bases de datos con Visual Basic .NET
neradas, per0 sin llegar a pulsar el b o t h Ejecutar consulta para evitar, por ejem-
plo, la eliminacih de 10s datos.
__ -
INTO Editonales
Editonales =
Edtoriales
M
I
Nota
Como en 10s demas casos, tambien puede acceder a la consulta SQL y modifi-
carla directamente, prescindiendo de 10s demas paneles de diseAo. Si conoce
el lenguaje SQL muchas veces le resultara mas rapido.
Programacidn de bases de datos con Visual Basic .NET
_ ~ I
~ _ _ -
l _ l l _ _ ~
"-____I
I______ ~ _ _ ^ _ _ _ I - ~ - - -
Para crear una nueva tabla, abra el menu emergente de la carpeta Tablas de la
base de datos sobre la que vaya a trabajar, eligiendo la opcion Nueva tabla. Si lo
que necesita es editar la estructura de una tabla existente, pulse el b o t h secunda-
rio sobre ella, en el Explorador de servidores, y elija la opci6n Diseiiar tabla.
En cualquier caso, tanto si la tabla es nueva como si ya existia, se encontrarti
con una interfaz similar a la que emple6 en Microsoft Access o SQL Server, en el
tercer capitulo, para crear las tablas de la base de datos de ejemplo. Una cuadricu-
la donde podri ir introduciendo el nombre de cada columna, su tipo de dato, lon-
gitud, etc. En la figura 13.18 puede ver, a la izquierda, la edici6n de la estructura
de la tabla L i b r o s de SQL Server, mientras que a la derecha se esti afiadiendo una
nueva tabla a la base de datos Oracle.
Inicialmente, al crear una nueva tabla, Visual Studio .NET le da un nombre pro-
visional del tipo T a b l a l . Cuando se finaliza el diseiio, y se cierra la ventana,
aparecera una pequefia ventana preguntando si desea crear la tabla y solici-
tando un nombre definitivo para ella.
A1 igual que ocurria a1 abrir una tabla para edicicin de datos, mientras disefia-
mos su estructura hace su aparici6n una paleta de botones especifica. Esta, como
se aprecia en la figura 13.19, cuenta con cinco botones cuyo nombre y finalidad, de
izquierda a derecha, son 10s siguientes:
Figura 13.19. Barra de botones especifica para el disefio de la estructura de una tabla
P T E R TABLE XOTT.TAELA1 Aw C C W 5 R A M
K-TABLA1 PRIMARV CY
Y
Figura 13.22. Definirnos una restriccion para evitar que el saldo de la cuenta
pueda ser negativo
Los datos obtenidos a partir de una vista pueden abrirse en Visual Studio .NET
como si de una tabla normal se tratase. Puede desplegar la carpeta Vistas de la ba-
se de datos SQL Server u Oracle y hacer doble clic sobre la vista LibrosPorEditorial
que se habia creado como ejemplo en un capitulo previo. Verd que el resultado es
una cuadricula de datos, como la de una tabla, per0 mostrando el resultado de la
consulta que define la vista.
Si abrimos el menu emergente asociado a esa vista, o a cualquier otra, veremos
dos opciones especialmente utiles: Diseiiar vista y Nueva vista. La primera permi-
te modificar la definicion de una vista existente, mientras que la segunda crea una
nueva vista. Recuerde que en el tercer capitulo usdbamos herramientas especificas
para efectuar estas tareas, mientras que ahora lo hacemos todo desde el propio en-
torno de Visual Studio .NET.
Prograrnacidn d e bases de datos con V i s u a l Basic .NET
IY I
/1 'ikl-SElEcr
WHERE
1Edlond
men
EDITOMALES NOKBRFAS
EDITORIALES, LIBROS
Edltorld', LIBROS LO ps Tib;lo;
friar0
LiiKOS P c C f i
[PREUO
31
- -- --
I_
- hnaya Mulmmeda s g l server 2000 10.75 I
Anaya Mulbmedia Guia paceca para uwarms IBuMm 7 10.75
nap itme medial Prwamaoon mn Visud Clt NET 39
I
Anaya Mulhmedla Programaooncor Vlwal s b h o NET 40
1- Anaya Multmmeda
Anaya Muitmedia
Programman con VISA B a x NET
Guia p a d m para uwarlos de Visual Basc NEl
39
10,75 I
1- Anaya Mulbmeda
Anaya Multmedla
---.ll.' -__
tuia paceca pala usuanos de Viyld S b h o NET
Programaooncon Deiphi 6 y Kyhx
- _---__
.-"A-r%h.l.L- ________
10,52
373
'DEl- -- J
---
Figura 13.23. Elementos para el diseiio de una vista
i r a Procedimiento almacenado
FJuevo procedimento almacenado
Actualizar
Las operaciones descritas en este punto son aplicables, igualmente, a las fun-
ciones, que pueden crearse, editarse y ejecutarse desde el entorno de Visual
Studio .NET.
Ahora que ya sabemos c6mo emplear las herramientas visuales de bases de da-
tos de Visual Studio .NET para preparar, o conocer, la informaci6n sobre la que
vamos a trabajar, el paso siguiente seri aprender a usar 10s componentes de acceso
a datos con que contamos. En realidad, esos componentes ya 10s conocemos, la uni-
ca novedad es que en lugar de crearlos mediante cbdigo, como en capitulos pre-
vios, usaremos operaciones de arrastrar y soltar y la ventana Propiedades.
Si inicia una aplicaci6n tipica Windows, o para la Web, veri que en la Caja de
herramientas existe una secci6n llamada Datos. En ella aparecen, como se aprecia
en la figura 13.27, 10s componentes OleDbConnection, OleDbDataAdapter,
OleDbCommand y 10s equivalentes para el proveedor SqlClient, asi como 10s
componentes genkricos Da taVi ew y Data Se t.
7
I
I/ 1 II
I/
Figura 13.28. Seleccion de 10s componentes correspondientes a 10s demas proveedores
re
Dependiendo del proveedor que desee emplear, haga doble clic sobre el com-
ponente Connection adecuado del Cuadro de herramientas, consiguiendo asi su
inserci6n en el m6dulo que tenga abierto en ese instante. Suponiendo que desee
acceder a 10s datos alojados en una base de datos Access o un libro de Excel, haria
entonces doble clic sobre el componente OleDbConnection. Este aparecersi en el
Brea de disefio, en la zona inferior, y sus propiedades estarian visibles en la venta-
na Propiedades.
La unica propiedad que tendremos que editar sersi Connectionstring, a fin
de facilitar la informaci6n de conexi6n necesaria. Esta propiedad cuenta con una
13. Herramientas visuales de datos
OleDbConnectior~l.
Open ( )
-~
Con 10s componentes Command, por ejemplo OleDbCommand, prepararemos
10s comandos de selecci6n de datos que precisemos. La unica diferencia es que
ahora el componente se crea a1 insertarlo en el disefiador, creandose automatica-
mente la variable, y las propiedades del comando se establecen visualmente. Nos
encontraremos, no obstante, con exactamente las mismas propiedades que ya co-
nocimos en capitulos previos, lo unico que cambia es la forma de crear el objeto y
personalizarlo.
Asumiendo que tiene en este momento definida la conexi6n del punto previo,
inserte un OleDbCommand, simplemente haciendo doble clic sobre 61 en el Cuadro
de herramientas, y edite en la ventana Propiedades las propiedades siguientes:
Programacidn de bases de datos con Visual Basic .NET
deherrmentas s
OradeDataMaptcr
>
A
1
Y
>
nulo Aubr Preoo
>
Figura 13.31. Asociaciones entre tablas de origen y tablas del conjunto de datos
s
El penultimo paso, en cuanto a tareas de diseiio se refiere en este simple ejem-
plo, ser6 la creaci6n del conjunto de datos, para lo cual hacemos doble clic sobre el
elemento DataSet que aparece en el Cuadro de herramientas. Como en el caso del
13. Herramienfas visuales de dafos
ai Z
Para ver el contenido del Data S et en esta ocasi6n no usaremos la consola, sino
que disefiaremos una sencilla interfaz de usuario. Abra la secci6n Windows Forms
Programacidn de bases de datos con Visual Basic .NET
________ - E
A
~
0Wndow
Tw, Left
0Wndow 8
IAmworkspace M
FixedD
[z1 AcbveCapbon
AcbveCapbanText
Llsto I
OleDbDataAdapterl.Fill(DataSet1)
No es mucho codigo, especialmente si lo comparamos con algunos de 10s ejem-
plos de capitulos previos y el resultado obtenido que, en este caso, seria el de la fi-
gura 13.34. Una rejilla en la que podemos navegar por 10s datos.
FraTx-iscu'Itsrte
IntrodLccior a la programion Farcisco Charte
Marual a.anzado Grcel :W2 Frapcisco Charte
F,lawal &I microrrocesador 33386 Ckris H Pappas&'Allialr H Murra, Ill 40
Programaacn C G Oelph ~ 6, K , h Frarcisco Charte
P r o g a r x i o r c w t/lsbal b s i c NET Frarcisco Chide
Frsrcisco Chide
sLal Studio NET
No cabe duda, usando 10s componentes de conexi6n a datos como hemos hecho
en 10s puntos previos, insertandolos en un disefiador y personalizandolos median-
te el us0 de la ventana Propiedades, ahorramos una cantidad importante de traba-
jo respecto a la escritura de c6digo para efectuar todo el proceso. Tan s610 hemos
tenido que escribir una sentencia para conseguir una cuadricula de datos que mues-
tra el resultado de una consulta SQL, sin necesidad de recorrer filas, acceder a co-
lumnas y acciones similares mediante c6digo.
No obstante, el trabajo puede simplificarse atin mAs mediante la creaci6n automi-
tica de parte de 10s componentes que, en 10s anteriores puntos, hemos ido inser-
tando y personalizando de manera individual. A continuaci6n vamos a tratar de
obtener el mismo resultado, o similar, con menos pasos y en menor tiempo. Puede
partir de un nuevo proyecto o bien eliminar el c6digo y 10s componentes que inser-
t6 en el ejemplo previo.
Tras pulsar el b o t h Siguiente > nos encontramos con el apartado Elija un tipo
de consulta. En ella, s e g h se ve en la figura 13.36, podemos elegir entre tres op-
ciones distintas:
Usar instrucciones SQL: Para actualizar 10s datos, en caso de ser necesario,
se emplear6n sentencias SQL del tip0 UPDATE, INSERT o DELETE. Estas se
generarin automiticamente para nosotros a partir de la sentencia de selec-
ci6n que facilitemos en el paso siguiente.
0 Crear nuevos procedimientos almacenados:En lugar de preparar comandos
con sentencias SQL, esta opci6n crea en el RDBMS un procedimiento almace-
nado para obtener 10s datos, otro para actualizar, otro para insertar y otro
para borrar, utiliz6ndolos cuando sea necesario. De esta forma las senten-
cias SQL ya se encontrarin compiladas en el RDBMS y el rendimiento ser6
superior.
13. Herramientas visuales d e datos
Si elegimos una de las dos primeras opciones, en nuestro caso nos quedaremos
con la que aparece seleccionada por defecto, en el paso siguiente tendremos que
introducir la sentencia SQL de seleccion de datos. Si 6sta es compleja, no tan sen-
cilla como la de la figura 13.37, puede pulsar el b o t h Generador de consultas pa-
ra diseiiar visualmente, utilizando la misma interfaz que ya conoce de ejemplos
anteriores.
Pulsando el b o t h Opciones avanzadas de esta ventana, en la parte inferior iz-
quierda, abrir6 entonces la ventana Opciones d e generacion SQL avanzadas (vea-
se figura 13.38). En ella aparecen tres opciones inicialmente activadas. La primera
provoca que el asistente genere, aparte del comando de seleccibn, comandos adi-
cionales para la insercih, actualizacidn y eliminacih. Con la segunda se conse-
guir5 que las instrucciones de actualizaci6n y eliminaci6n empleen el mecanismo
conocido como concurrencia optirnista, consistente en asumir que 10s datos no van a
cambiar desde que se recuperan hasta que van a modificarse, no bloqueando el
acceso a ellos. Por ultimo, la tercera opci6n provoca que tras cualquier actualiza-
ci6n se efectue una actualizacih inmediata del conjunto de datos, asegurando asi
que este siempre se mantiene en consonancia con el contenido real del origen de
datos.
Prograrnacion de bases de datos con Visual Basic .NET
1
o m avanzadas Genera& de comultas...
Tras pulsar el b o t h Siguiente > una vez mas, accedera a una ultima ventana de
resumen y confirmacibn. En ella se detallan las acciones elegidas, bastando la pul-
saci6n del b o t h Finalizar para cerrar el asistente y concluir el proceso. Si no esti
conforme con algo, aun esta a tiempo de pulsar el b o t h < AtrPs y corregir lo que
desee. A1 finalizar, apareceri en el disefiador el componente OleDbDa taAdapter
y un OleDbConnection.No existen, sin embargo, componentes OleDbCommand,
a1 menos aparentemente. Sin embargo, si examina el c6digo generado por el asis-
tente encontrara las siguientes declaraciones justo antes del mktodo 1 nit i a 1i ze-
Component ( ) :
Friend WithEvents O l e D b S e l e c t C o m m a n d l As ~
System.Data.01eDb.OleDbCornrnand
Friend Wi thEvents 01 e Db I n s e r t C o m m a nd 1 As ~
System.Data.01eDb.01eDbCommand
Friend WithEvents OleDbUpdateCornrnandl As ~
S y s t e m . Data. O l e D b . O l e D b C o r n r n a n d
. "
Puede cambiar la configuracion de un adaptador de datos en cualquier mo-
mento, mediante el mismo asistente empleado para crearlo, usando el enlace
Configurar adaptador de datos que aparece en la parte inferior de la ventana
Propiedades mientras tiene seleccionado el adaptador, o bien eligiendo la op-
cion homonima del menu emergente del OleDbAdapter.
Aunque en principio parece que tan s610 se ha aiiadido el esquema XSD, si pul-
sa el b o t h Mostrar todos 10s archivos del Explorador de soluciones verd aparecer,
asimismo, un m6dulo llamado D a t a S e t 1.vb. Abralo y eche un vistazo a su con-
tenido. En el encontrard una clase llamada Data S e t 1 derivada de Data S e t . Esta
clase cuenta conuna propiedad s610 de lectura, llamada L i b r o s , de tip0 L i b r o s -
D a t a T a b l e , una clase definida mds adelante en la que encontrard objetos Data-
C o l u m n con nombres que le resultardn familiares, a1 coincidir con 10s nombres de
las columnas de la tabla L i b r o s .
Lo que ha hecho el asistente anterior es generar un conjunto de datos con t i p , una
clase que, derivada de Data Se t, implementa 10s elementos necesarios para facili-
tar el acceso a las tablas y columnas, asegurando a1 tiempo la validez de 10s tipos.
La existencia de este conjunto de datos con tip0 hace que sentencias como &ta:
DataSetll.Tables(”1,ibros”) .Rows ( 0 )( “ E d i t o r i a l ” ) = 3
DataSetll.Libros(O).Editorial = 3
Los conjuntos de datos con tip0 evitan ciertos errores, como la asignacion de
valores de tipos incorrectos, produciendo 10s avisos durante la compilacion,
cuando es facil corregirlos, en lugar de en ejecucion.
Como ha podido ver en este capitulo, el entorno de Visual Studio .NET cuenta
con potentes herramientas para el trabajo con bases de datos, simplificando tareas
como la edici6n local de datos o informacion de esquema, incluso cuando se opera
sobre un origen de datos remoto. Visual Studio .NET facilita, asimismo, la depura-
cion de procedimientos almacenados SQL Server desde el propio entorno, lo que
nos ahorra cambiar del entorno de desarrollo a1 de la base de datos a1 depurar una
aplicacion que tenga embebidas parte de las reglas de negocio en el servidor de
datos.
Los componentes que en capitulos previos creAbamos mediante codigo, como
10s adaptadores de datos, comandos y conjuntos de datos, pueden tomarse desde
el Cuadro de herramientas, insertarse en un diseiiador y personalizarse mediante
la ventana Propiedades. En ocasiones, tal como se ha visto en 10s ultimos puntos,
la mayor parte del proceso de configuracih puede efectuarse automAticamente,
gracias a las opciones, asistentes y la posibilidad de arrastrar elementos, como las
tablas y vistas, directamente desde el Explorador de servidores hasta un diseiiador.
Una vez que sabemos c6mo conectar con 10s origenes de datos y definir adap-
tadores, comandos y conjuntos de datos, en el capitulo proximo veremos c6mo co-
nectar esos elementos con controles de interfaz, incluido el control DataGrid que
hemos usado en el ejemplo de este capitulo.
La presentaci6n y solicitud de datos a travks de la consola, empleada en 10s ejem-
plos de 10s capitulos de la segunda parte del libro, no es precisamente el mecanis-
mo m i s flexible ni amigable para comunicarse con 10s usuarios de sus aplicaciones.
Es mucho m6s habitual la elaboracion de interfaces de usuario basadas en venta-
nas, ejecut6ndose por ejemplo sobre Windows, o bien las interfaces Web, accesi-
bles desde un cliente como Internet Explorer. Aunque podriamos, mediante cbdigo,
obtener 10s datos para presentarlos a1 usuario en componentes propios y, tambikn
mediante ccidigo, recuperar 10s cambios efectuados por el usuario para transmitir-
10s a1 origen de datos, lo cierto es que la mayor parte de ese proceso puede auto-
matizarse gracias a la existencia de la vinculaci6n a datos en ciertos componentes.
Mediante la vinculaci6n a datos, o data-binding, es posible enlazar una vista, ta-
bla o conjunto de datos con uno o varios controles de interfaz, ya Sean Windows o
Web, automatizando la presentacih y recuperaci6n de cambios. De esta forma
nuestro trabajo se reduce en gran medida.
El objetivo de este capitulo es introducir 10s conceptos de vinculacih a datos,
asi como 10s controles m6s interesantes en este aspecto. En el capitulo siguiente
nos centraremos en el disefio de formularios de datos empleando estos controles.
La vinculaci6n entre 10s origenes de datos y 10s controles puede ser de varios
tipos, segun que el control sea Windows o Web y tambien dependiendo de que
14. Componentes con vinculacidn a datos
pueda mostrar una sola columna de una fila o bien multiples filas o columnas. En
realidad, la vinculaci6n puede efectuarse no solo con una vista, una tabla o un con-
junto de datos, sin0 tambikn con una lista, un arreglo y, en general, con cualquier
componente que implemente la interfaz I Li s t.
Los controles que se utilizan habitualmente para disefiar interfaces de usuario,
independientemente de que Sean nativas Windows o de tip0 Web, pueden clasifi-
carse, en cuanto a su vinculaci6n a datos, en las tres categorias siguientes:
0 Controles que tan solo precisan el contenido de una columna de una cierta
fila, por ejemplo 10s TextBox y similares.
0 Controles capaces de mostrar el valor que tiene una cierta columna en mul-
tiples fhas, por ejemplo un ListBox o ComboBox.
0 Controles tip0 cuadricula en 10s que aparecen multiples filas con multiples
columnas, como el DataGrid que usibamos en uno de 10s ejemplos del ca-
pitulo previo.
Suponga que tiene un DataSet en el que ya existen dos DataTable, uno con
libros y otro con editoriales, y que desea vincular la columna Titulo de la tabla
Libros con la propiedad Text de un TextBox, para facilitar la visualizacih y
manipulacih por parte del usuario.
Asumiendo que el TextBox se llama TextBoxl y que tenemos un DataSet
llamado DsLibrosl con la tabla Libros, aiiadiriamos el enlace con una sentencia
como la siguiente:
T e x t B o x l . L l a t a B i r d i n j s .Add (New
~
Las expresiones de enlace se delimitan entre 10s caracteres < % #y %>, marcas
que provocan la resoluci6n en el servidor y no en el cliente. DataBinder es una
clase con la que cuentan las paginas ASP.NET, cuyo objetivo es facilitar el enlace
con origenes de datos tipicos, como conjuntos de datos y vistas. Lo unico que hay
que hacer es facilitar a su metodo Eva1 ( ) la referencia a1 origen, en este caso un
DataSet, y una cadena para seleccionar de 61 una cierta columna.
False
Top, Left
TWt
0 Rindow
FixedD
True
Normal
(ningunoi
IBearn
ilD"e
True
Microsoii Sans Serif, 3 25pt
NindowText
True
EiKrnboi
(Nmsuno)
(Nmguno)
[Nmguno)
(Nwno)
Wmguno)
@nguno:
pimguno)
(Nmguno)
(Niguno)
(Nmguno)
WrnSUnQ!
(Nmguno)
(Nmguno)
(Nmguno)
(Nmguno)
iblinguno)
DsLibrosl Libios Tltulo
(Nmguno)
“mguno)
INnauno)
....a+&.y,T.. ..............................
. . . . . . . -. ...................... . . . . . . . . . . . . . . . . . . . . . . .“.”. . ‘fti
S d e o a r la popedad que desea mlarar. p. cmtmuaom,Utiliie el enlace wrrde para enlarat
:on LCI d a n n t o de d a i s y enatleca el f m ! o o ~ t i l N~ de a c e p r w n d i z a d o ma solbr
m ewesh de enlace.
BackCdor
I BorderColM
I BwderSMe
Borderwidth
+ 0 Editorial
Columns
+ 0 IDLibro
I CssClasr
Enabled
+ U Preoo
+ Y
+ Font
Son varios 10s componentes capaces de mostrar el valor que una cierta columna
tiene en multiples filas, siendo 10s mas habituales ListBox y ComboBox. Cual-
quiera de estos dos componentes puede ser usado para ofrecer a1 usuario una lista
de valores a elegir, tornados de una columna de una tabla, asociando dichos ele-
mentos con el valor que tenga, en la misma fila, cualquier otra columna. El usuario
podria, por ejemplo, elegir el nombre de una editorial de un ComboBox y el pro-
grama obtener el identificador de dicha editorial.
Aunque estos controles t a m b i h disponen de la propiedad DataBindings,
cuentan, ademfis, con propiedades especificas para el comportamiento especifico
que tienen. En el caso de 10s controles para formularios Windows dichas propie-
dades son:
Datasource: Contendra una referencia a la tabla, vista u objeto que vaya a
actuar como origen de datos.
DisplayMember: Alojara el nombre de la columna cuyo contenido se mos-
trar6 en la lista.
ValueMember: Indica la columna cuyo contenido se obtendrfi como valor
asociado a cada uno de 10s elementos de la lista.
_________ ~ -
rarnacion con Visual Studio NET
:*I
i
Guia practica para usuarios de Visual Studio NEl/
Programacion con Delphi 6 y Kylix
Guia practica para usuarios de Delphi 6
‘Manual avanzado Excel 2002
Guia practrca para usuartos de Excel 2002
Guia practica para usuarios de Kylix
lntroduccion a la programacion
Manual del microprocesador 80386
Assembly Language Step-by-Step
Figura 14.5. Vinculacion de una lista ASP.NET con 10s valores de una columna
14. Componentes con vinculacion a datos
mantener una lista de objetos, uno por cada origen de datos que exista, que se en-
cargarin de la sincronizacih de todos 10s componentes vinculados a un mismo
origen. Los elementos de Bindingcontext son de tipo BindingManagerBase,
una clase abstracta que cuenta con dos derivadas: CurrencyManager y Proper-
t yManager.
La clase PropertyManager se usa para mantener la asociaci6n entre la propie-
dad de un control y un origen cuando no hay necesidad de saber qu6 fila de ese
origen es la actual, caso 6ste en el que se emplearia un CurrencyManager. Siem-
pre que el origen sea un DataTable, DataView o similar, el objeto encargado de
mantener la asociaci6n seri un CurrencyManager.
Como ya sabe, lo ha visto en 10s capitulos de la segunda parte, una vez que se
ha recuperado informacion en un DataTable 6ste contiene todas las filas de da-
tos, a las que puede acceder como si de un arreglo se tratase. No existe una propie-
dad que indique qu4 fila es la actual, ya que ese concepto, muy habitual en otros
sistemas de acceso a datos, no existe en ADO.NET.
Cuando ese DataTable o DataView se enlaza con controles como TextBox,
CheckBox y RadioButton, sin embargo, existe la necesidad de saber c u d de las
filas de esa lista de datos tiene que mostrarse en 10s controles, es decir, cu6l de las
filas es la posicion actual dentro de la lista. Como ADO.NET no ofrece esa funcio-
nalidad, lo que hacen 10s formularios Windows es crear un CurrencyManager
para cada origen que mantiene una lista de datos, como 10s mencionados Data-
Table y Dataview.
Dado que en un mismo formulario podrian existir multiples CurrencyManager,
bien porque existan varios origenes de datos o un mismo origen con enlaces no
homog6neos a varios controles, para mantenerlos todos ellos se emplea un objeto
Bindingcontext.
Conociendo el nombre del origen de datos, es ficil recuperar el CurrencyMa-
nager asociado:
B i n d i n g C n r ~ t e x (t D s L i b r o s l , "Libros" )
datos, contando con propiedades que nos permiten conocer y modificar dicha PO-
sicion. La mayor parte de 10s miembros de esta clase son heredados de Binding-
ManagerBase, si bien CurrencyManager sustituye algunas implementaciones
por otras mds especificas.
En cuanto a posicion se refiere, las dos propiedades de mayor inter& que tiene
esta clase son Count y Position. Como puede suponer, la primera indica el nu-
mero de filas existentes en el conjunto, mientras que la segunda es un indice con
base 0, por lo que el valor mdximo serd el indicado por Count menos 1.
Conociendo tan s610 estas dos propiedades, es fdcil afiadir a un formulario 10s
controles de navegacion cl6sicos para que el usuario pueda ir fila a fila por el con-
junto de datos.
, . .-..._(^._.-.....__I.--..
_^__I .
x_I.-.-., ....- _.___^__I__x.” ____^._
.__.
ll_ll ~ _ _ _ ~ _ ^ _
, . ,, . .' . ..
. . . .' '. .. I . ,
Debe tenerse en cuenta que 10s clientes que vayan a usar una aplicacion Web
en la que se utiliza vinculacion a datos, tienen que instalar en su sistema 10s
MDAC: Puede aiiadir a 10s propios formularios ASP.NET la informacion nece-
saria para que 10s obtenga e instale.
En caso de que vaya a diseiiar una pdgina ASI'.NET con vinculaci6n a datos,
por ejemplo para mostrar las editoriales o libros existentes en nuestra base de da-
Programacidn de bases de datos con V i s u a l Basic .NET
sq
Da
DataBind ( ) '
SylConnectionl. C use ( )
s
Si a pesar de la existencia de componentes como DataList y Repeater, que
pueden enlazarse a una lista de datos, decide emplear componentes con vincula-
ci6n simple, seguramente precisara un medio de navegaci6n por la lista de datos,
de tal forma que 10s controles muestren en cada momento la informaci6n de la fila
actual.
14. Componentes con vinculacidn a datos
5eleccime la propiedad we derea enbzar A conbnuaci6nn.Ubltce el enlace simple para enlazar con un
elernento dedab5 y establecer el forrnato o &re el enlace persoMflzado para e s a w ma eqxeu6n
ropedades enkables
AccessKey
Backcolor
BotderColw
Borderswle
BordeiWidh
cssc1ass
Enabled
+ Font
Forecolor
Height
ToolTip
Visible
Width 6 Eapresdn de e n k e p s r m l ~ z a d a :
Sessicrl ("Cirunt" 1 = D s L i b ~ u . ~L li b r u s . r o i i r ~ t
Se-sion("Position") = I)
DataBind ( )
End If
End Sub
ByVal e As S y s t e m . E v e n t A r g s ) Handles B u t t r ! n l . C l i c k
Dim Eori t 1 !n As I
S e s i i o n ( C o u n t ) - 1 Then
P o s i t i o n += 1 '
Sessi ~ n ( " P o s i t i o r ~ " =
) Poiition
DataBind ( ) '
End I f
End Sub
Priva C l i c k (B e r l d c r As S y s t e m . Obi e c t ,
ByVal e As S y s t e m . E v e n t A r g s ) Handles B u t t o n 2 . C l i c k
Dim P o s i t "Prrsltlori")
P o s i t i o n -= 1
Session ( " P o s i t i o n " ) = tosition
DataBind ( ) '
End If
End Sub
sy - - + I 2
awx
llek~O$BDD~aual6a~1d.l~/l4~a.egarASP/WebForm1
Francisco Charte
Figura 14.10. La pagina con las dos cajas de texto y 10s botones que permiten
avanzar y retroceder entre filas de datos
Nuestro objetivo es crear un formulario con una relacibn maestro/ detalle entre
las tablas E d i t o r i a l e s y L i h r o s , usando para ello dos controles D a t a G r i d , de
tal forma que, a1 seleccionar una editorial en el primero, aparezcan automdticamen-
te en la rejilla de detalle 10s titulos que correspondan. No necesitamos definir una
conexibn, ni tomar las tablas desde el Explorador de servidores y arrastrarlas so-
bre un formulario, ya que todo ese trabajo lo efectuard el asistente.
La primera pdgina del asistente es tan s610 informativa, indicdndonos cud1 es
su finalidad, bastando con pulsar el b o t h Siguiente > para dar el primer paso.
Seleccicin del
En nuestro caso partimos de un proyecto inicialmente vacio, per0 igualmente
podriamos haber invocado a1 asistente tras definir un D a t a S e t a partir del origen
de datos que nos interesase. El primer paso del asistente nos permite, tal como se
aprecia en la figura 15.2, tanto crear un nuevo conjunto de datos como w a r uno
que ya existiese en el proyecto.
Deje elegida la primera opcibn, en realidad no puede activar la segunda ya que
el asistente ha detectado que no hay n i n g h D a t a S e t existente disponible, e intro-
duzca el nombre que desea dar a1 conjunto de datos, por ejemplo d s l i b r o s .
En este conjunto de datos, tal como veremos despuks, se introducirdn las tablas
E d i t o r i a l e s y L i b r o s , asi como un objeto D a t a R e l a t i o n para relacionarlas.
Todo ese trabajo, que en 10s capitulos de la segunda parte efectudbamos mediante
cbdigo, ser5 ejecutado por el asistente.
Programacidn de bases de datos con V i s u a l Basic .NET
xi6
El DataSet tiene que recuperar la informaci6n de un origen de datos, para lo
cual es precis0 facilitar una conexion. Esta puede encontrarse predefinida, en el
Explorador de servidores, o bien crearse a prop6sito en ese mismo momento. Es la
tarea del paso siguiente del asistente, cuya ventana se muestra en la figura 15.3.
Si tenemos una conexion definida que nos sea util, no tenemos m6s que desple-
gar la lista que aparece a la izquierda para elegirla. De no ser dse el caso, pulsaria-
mos el b o t h Nueva conexidn y definiriamos la nueva conexion con el cuadro de
didlogo que ya conocemos de capitulos previos.
En este caso hemos elegido la conexi6n que teniamos definida para acceder a la
base de datos SQL Server que se encuentra en el servidor Inspiron. En su caso, co-
mo es logico, la conexi6n seri otra diferente dependiendo de d6nde estd ejecutdn-
dose SQL Server o bien MSDE. Tambidn puede optar por conectar con un origen de
datos distinto, cualquiera de 10s que cre6 en el tercer capitulo.
I S r l Nueva L o n e ~ ...
n
Como puede verse en la figura 15.4, hemos elegido del origen las tablas Edi-
t o r i a l e s y Libros, que ahora aparecen en el panel de la derecha en lugar de ha-
cerlo en el de la izquierda. Pulse el b o t h Siguiente > una vez m& para continuar
en el punto siguiente.
Ciertos pasos del asistente dependen de 10s elementos que se elijan aqui. Al
haber seleccionado dos tablas, por ejemplo, deberemos definir una relacion
entre ellas, algo que no seria preciso si hubiesemos seleccionado una vista o
un procedimiento almacenado. A cambio, sin embargo, podria ser necesario fa-
cilitar una lista de parametros de entrada.
El asistente crea un adaptador de dam5 para rdlenar el conjunto de datos de las CaMas o las
wstas dlsponibles. SIsekccrona mis de un elemento, puede estaMecer una rela& enbe ellos
en el squiente paso.
1
Llbros
vistas
_1_1
Figura 15.4. Seleccionamos las tablas con las que va a generarse el formulario
En este paso del asistente, dado que en el anterior hemos elegido como elemen-
tos dos tablas, tendremos que establecer esa relacidn, per0 sin necesidad de crear
de manera explicita el objeto D a t a R e l a t i o n . En su lugar (vkase figura 15.5) bas-
tar6 con indicar cud1 es la tabla maestra y la de detalle, seleccionando las columnas
de enlace. Hay que pulsar el b o t h > para crear efectivamente la relacidn, momen-
to en que aparecera en la lista Relaciones.
La existencia de esta relaci6n es fundamental a la hora de crear una relaci6n
maestro/detalle, ya que sin ella no se sabria qu6 libros corresponden a la editorial
seleccionada en cada momento.
Que tomemos datos de dos tablas no implica que deban mostrarse todas sus co-
lumnas, aunque quiz2 sea 6ste el caso que nos interese. En cualquier caso, el paso
siguiente del asistente nos permitird elegir las columnas que deseamos tener en el
formulario. Tenemos nuevamente dos paneles bien diferenciados, segun se apre-
cia en la figura 15.6. En el de la izquierda elegimos la tabla maestra de la lista des-
plegable, marcando a continuaci6n las columnas que deseamos tomar de ella. De la
misma forma, en el panel derecho seleccionamos la tabla de detalle y sus columnas.
Crear una relacion entre las tablas
El asistente utilizara las relaclones para generar codigo que rnantenga las tablas
sincronizadas cuando habaie con ellas
paves:
IDEditorial
Figura 15.5. Definimos la relacion que existe entre las dos tablas
Tabla de &etaks:
i l-,l ILibros i
CQ!UKWW:
____
El tiltimo paso del asistente nos permite elegir el disefio que deseamos darle a1
formulario, existiendo dos opciones:
0 Todos 10s registros de la cuadricula: Emplea un control D a t a G r i d para
mostrar cada una de las tablas, facilitando la insercih, edici6n y borrado en
la misma rejilla de datos.
0 Registro unico en controles individuales: Se usan controles de interfaz tipi-
cos, como T e x t B o x y CheckBox, para mostrar la informaci6n fila a fila.
R m-celar tudo - Cancela lo5 cambios de to& lo5 relpsbos d d conjunto de datos
51selecciona conboles ir~lividualees,puede agregar controles para b edicim y b ex@ora&
r
r
r
r
Ahwa el asistente bene la informauon necesaria Haga dic en Fmakar para salir y generar el nwvo
formulano
Figura 15.7. Optamos por usar controles D a t a G r i d para mOStrar 10s datos
de las tablas
ForrnularloAsstpnte (1
IUClOn
FmdabAsiotente
References
3 Assernblylnfc vb
dstibras nsd
a hnhbrm rb
.r
ob)diiibras % OlrDbConnemonl boleDbDataAdaprer1 b OleDbDataAdapter2
Nota
i
- __ -_I__ - - - - - _ _ _ - ~
Ademas de todos 10s controles que pueden verse en el formulario, con sus
propiedades debidamente establecidas, el asistente tambien ha generado el c6digo
necesario para recuperar 10s datos, actualizarlos y cancelar 10s cambios efectua-
dos. Analicemos brevemente ese c6digo para saber exactamente qu4 ocurrir6 a1 eje-
cutar el programa.
Tras abrirse el formulario este permanecerti vacio esperando una acci6n por
parte del usuario. Lo habitual es que se pulse el boton Cargar que provoca la eje-
cuci6n del c6digo siguiente:
H a n d l e s b t r l L o a d . r1ic-C
T rY
P u b l i c Sub L ( arjIiataSet! )
Dim 3biDataSetTernp As F o r m u l a r i u A s i ? t e n t e . d s L 1 b r c r s
o b i D a t a S e t T e m p = N e w Furmulari~,A-lstente.dsLlbros( )
T rY
Me.FillP3taSet (ob]DdtaSetTemp)
Catch e Fi 11 Dd t aSet As Sys t e m . E x c e p t i u r i
Programacidn de bases de datos con Visual Basic .NET
Una vez introducidas en el Data S et todas las filas de las dos tablas, se devuel-
ve el conjunto de datos de nuevo a1 metodo LoadDataSet ( ) . fistelirnpia el DataSet
existente en el formulario, llamado ob jdslibros, e introduce en 61 las filas obte-
nidas por la llamada a Fi 11Data Set ( ) . En ese momento el formulario ya apare-
ceria con la lista de editoriales en el primer DataGrid y la de libros en el segundo,
como se aprecia en la figura 15.9. Podemos cambiar de editorial para ver sus libros,
aiiadir entradas, eliminarlas y modificarlas.
oblDataSetChdnyes CType[objJrLibr b . b e t C h a r ~ g e s , ~
Fo L mi 1 1a L 1oA. 1 it F rl t e . d c I, I b L I
o b l 3 s L i b r o s . M e r g e [ o b jD a t a S e t r h a n y e s )
o b ] d ~ L i b r o s. A c c e p t C t i a n g e c . ( )
Catch e U p d a t e As S y s t e r n . E x c e ~ t i o n
Throw eUpdat e
End Try
End If
End Sub
OleDbDataAdapter1,Upjate (ChangedRows)
OleDbDataAdapterZ.lipdate (ChanqedRuws)
End I f
Catch u p d a t e E x c e p t i i n As Sy-tern.E x c e p t i o n
End Try
End Sub
Nota
abC
~ _ _ _ ~ p -
x_II.--
El c6digo de este formulario ASl'.NET es tambien mAs simple que el generado
para el formulario Windows, lo cual no es de extraiiar ya que no existen capacida-
des de edici6n. El primer metodo en ejecutarse serh el correspondiente a1 evento
C1 i c k del unico b o t h que hay en la piigina:
P r i v a t e Sub S t i i r w D e t a i l G r i d ( 1
If ( M e . m a s t e r ~ a t a G r i d . S e l e c t e S I n d P x <> - 1 ) T h e n
D i m F ' a r e r l t K o w s As S y s t e m . D d t a . r ) a t a V i e w
D i m c h i l d R l J w s As S y r t e r n . Dat~,i. DataView
D i m c u r r e r l t P a r P n t R u w As System. Data. DataRbwView
M e . cl b jd sL i b r o s = C T y p e ( A p p 1 i c a t i o n ( " iib j d.5 Li b r o r " ) ,
Fci rr,,i
\ 1.:
....... ......................... ..................... ......
1General
J Columnas r grear columnas a u t m d t k a m t e en tempo de ejecucion
Lrsta de ED ____ _
3 Paginacmn Columnas disponrbles: Columnasselecaonadas
d Formato
0 C o b m enlazada
3 Bordes
Columna Hipervinculo
W Columna Plantilla
I
Expresih de _wdem&n:
r] p yisibb
.
I
Cancebr 1 I I Ayuda I
Figura 15.12. Aiiadimos a la rejilla una nueva columna para el boton de edicion
Handles d e t a 1 1 Da t a Gr i d . C a n ce 1 Cornmarld
detailDataGrid.EditIternIndex = -1
ShowDetailGrid ( ) '
End Sub
ByVal e As System.Web.UI.WebContro1s.DataGridC~~mmar~dEver~tArgs)
Dim F l L d AS dsLibros.LibrosRow = ~
CType(e.Item.Cells(l).Controls(O),TextBox).Text)
. 1 LOlS(O),
.Titulo = CType(e.Item.Cells(3).Controls(O),TertBox).Text
.Autor = CType(e.Item.Cells(4).Controls(O), TextBox).Text
. E d i t o ~ i a l CType(e.€tem.Cells(S).Cor~trols(O),
~ ~
TextBox).Text
.Precio = CType(e.Item.Cells(G).Controls(O),TertBox).Text
End With
End If
de d.Ed
ShowDetailGrid() '
End Sub
la que contiene 10s enlaces de edition, asi que el identificador del libro se encuen-
tra en la segunda y 10s demiis datos en las siguientes. Los recuperamos asignando-
10s a las columnas de la fila en el Data S e t.
Si ejecuta el programa en este momento, verii que puede efectuar cambios y
que, tras pulsar el enlace Actualizar, &tos permanecen ahi, en el DataSet,per0 si
comprueba el origen de datos, o simplemente sale del programa y vuelve a ejecu-
tarlo, comprobara que esos cambios se pierden. Tenemos que actualizar el origen
de datos.
ii
2 811
___ -__-_
No tiene sentido actualizar la informaci6n con el origen cada vez que se modi-
fique una columna, asi que necesitaremos aiiadir un b o t h o enlace para que dicha
actualizacion se efectue a demanda. Como se aprecia en la figura 15.13, insertare-
mos ese b o t h a la derecha del que ya existia en la parte superior de la pagina
P a g e . R e s p o r i s e . W r l t e ( E x c e p c l >n.Messaye)
End Try
E n d Sub
Podriamos haber dado todos 10s pasos que se ejecutaban en el c6digo generado
por el asistente de formularios Windows para efectuar la actualizacih, per0 he-
mos optado por algo mucho m6s directo. Recuperamos la referencia al DataSet y
lo usamos directamente como parhmetro del mktodo Update ( ) del segundo adap-
tador de datos.
El efecto, si lo comprueba, es el mismo, se escriben 10s cambios en el origen de
datos complethdose el ciclo que le permitir6 editar la informacih desde un nave-
gador Web.
15. Formularios de datos
Este ultimo capitulo dedicado a1 estudio de 10s elementos de Visual Studio .NET
relacionados con el acceso a datos, le ha servido para conocer dos de 10s asistentes
m&spotentes con que cuenta el entorno, mediante 10s cuales pueden generarse for-
mularios con controles vinculados a datos tanto en aplicaciones Windows como en
aplicaciones Web.
Ha podido ver que el asistente para formularios Web genera menos funciona-
lidad que el equivalente para Windows, y t a m b i h c6mo suplir dicha deficiencia
con la personalization de las columnas del D a t a G r i d y la escritura de algunas
sentencias.
En resumen, 10s capitulos de esta tercera parte le han facilitado gran parte de la
informaci6n que necesitari para crear interfaces de usuario, Windows o Web, con
controles vinculados a 10s elementos que conoci6 en la segunda parte, principalmen-
te conjuntos de datos, tablas y vistas.
Los capitulos de esta ultima parte del libro, en general mucho m6s breves que
10s anteriores, le explican c6mo abordar casos concretos, generalmente de forma di-
recta mediante algun ejemplo.
En algunos de ellos se resume informaci6n vertida en capitulos previos, o bien
se profundiza en temas que, a pesar de haberse tratado anteriormente, no se ha he-
cho con detalle.
En este decimosexto capitulo, que es el primer0 de la cuarta parte, el objetivo es
codificar un ejemplo en el que se conecta con un origen de datos y se recupera in-
formacibn, como en 10s capitulos previos, per0 sin emplear directamente las cla-
ses especificas de cada proveedor a lo largo de todo el ddigo, sino tan s610 en un
punto.
De esta forma conseguiremos una conexi6n gen6rica muy fiicil de modificar,
incluso en ejecuci6n a demanda del usuario.
3 (I-
Figura 16.1. Diseiio del forrnulario
e funciones
El paso siguiente ser6 la codificaci6n de 10s procedimientos y funciones necesa-
rios para abrir la conexi6n y recuperar 10s datos a partir del comando de seleccibn
que se haya introducido.
Comenzaremos escribiendo la declaraci6n de las cuatro variables siguientes a1
inicio del m6dulo:
Dim Coriexion As I D b C o n n e c t i o n
Dim Comando As IDbCommand
Dim A d a p t a d o r As I D b D a t a A d a p t e r
Dim d s D a t o s As D a t a S e t
Programacidn de bases de datos con Visual Basic .NET
Case 2 '
Co riex 1 o 1Connection ( -
" D a t a S o u r c e = I n s p i r o n ; I n i t i a l Catalog=" &
~
Return F a l s e
E n d Select
C'onarldb = C o r e ~ i o nC. r e a t e C o m m a r d ( )
R e t u r n t b r i m a n d o . T e x t <> ""
End Function
P r i v a t e Sub A b r i r C o r L e x i o n ! )
Conexion.Open! )
C a t c h E x c e p c i o r l As Except i o n
MesqageBox.Show(Excepclori.Message)
End Try
E n d Sub
P r i v a t e Sub RecuperarDatosO
Comando.CornrnandText = tbComando. T e x t
16. Conexidn genLrica
mand
C o n e x i o n . Close ( )
E n d Sub
Observe que el DataSet se crea nuevo cada vez que se ejecuta el metodo
RecuperarDatos, de no hacerse asi, dos llamadas consecutivas al metodo,
con comandos identicos o diferentes, causarian que el conjunto de datos fuese
una combinacion de ambos resultados.
P r i v a t e Sub VincularRe]illa ( )
DataGrid1.DataSource = dsDatos
Da t a G r 1 d 1 . D a t aM emb e r = " T ab 1 e "
End Sub
De partida, como es 16gic0, deber5 contar con un servidor en el que est6 ejecutin-
dose el RDBMS de Oracle, conociendo el servicio a1 que quiere conectar, el nombre
del esquema y la clave de acceso. Seguramente la empresa para la que vaya a traba-
jar ya tenga el RDBMS instalado y en funcionamiento, per0 tambi6n es seguro que
Programacidn de bases de datos con Visual Basic .NET
Bienvenido
Haga clic en "Productos lnstalados '' para ver todos los productos
Lo primer0 que tenemos que hacer, antes incluso de elegir el product0 que que-
remos instalar, es facilitar un nombre para el directorio raiz donde se efectuarri la
instalacih, junto con el camino completo en el que se crearri dicho directorio. De
ser necesario, facilitariamos en el apartado Origen el camino y nombre del archivo
j a r donde se encuentra el indice de productos que hay en 10s CD. Esto habitual-
mente no es necesario.
El instalador propone un directorio raiz por defect0 que es el que puede verse
en la figura 17.3. Lo aceptamos y pulsamos de nuevo el b o t h Siguiente.
17. Acceso a Oracle desde Visual Basic .NET
Origsn...
IntroduZCa l a ruta
Ruta de ACC~SO
Productos Disponibles
r Oracle91 Clent 9 0 1 1 1
degeslandcEatarpnse hbrsemmsdered
r Procesamlentode Transacctones
Figura 17.5. Optamos por crear una base de datos para us0 general
La ubicaci6n de las bases de datos que vayan cre6ndose suele ser el directorio
o r a c l e \ o r a d a t a de la unidad donde se haya instalado Oracle. El siguiente paso
17. Acceso a Oracle desde V i s u a l Basic .NET
del asistente, no obstante, nos permite especificar el directorio que deseamos em-
plear, pudiendo dejar el indicado por defecto o cambiarlo.
. . . . .'2-s
... kill
, .... - .. ._I_. . . __ -
I . r o m n ~ e a e l a B 3 s e a e D a l o s G ~ aL ~t ar ~x -111 x l - i r w ~3 E i j
... ....
I/ l
Libros I
El paso siguiente serfi la elecci6n del conjunto de caracteres que se utilizara pa-
ra almacenar la informacih en la base de datos. Tendremos tres opciones: el juego
de caracteres por defecto del sistema, el juego de caracteres Unicote o bien cual-
quier otro que nos interese seleccionfindolo de una lista.
Llegamos a la ventana resumen de la instalacih, mostrada en la figura 17.7. Es
el punto en el que debemos revisar todos 10s parhmetros y a continuacih pulsar el
b o t h Instalar, si todo es correcto, o bien retroceder y cambiar aquellas opciones
que deseemos.
Tras pulsar el b o t h Instalar nos limitaremos a ir cambiando el CD-ROM del
producto, a medida que lo solicite el instalador, o bien indicar el directorio donde
se encuentra el contenido de cada uno de ellos, en caso de que hayamos dejado 10s
paquetes descomprimidos en directorios individuales.
A1 final de la copia de archivos se pondrh en marcha la configuracih de las dis-
tintas herramientas. Se iniciarfi el servidor HTTP de Oracle (una versi6n personali-
zada de Apache), el agente inteligente de Oracle y, como se aprecia en la figura 17.9,
se invocarfi a1 asistente de configuracih de bases de datos.
El proceso de generacih de la base de datos, en el que prhcticamente no ten-
dremos que intervenir, irh abriendo algunas ventanas de consola que se cerrarhn
automfiticamente, no tiene que actuar sobre ellas. El proceso de creaci6n de la base
de datos quedar6 reflejado en una pequeiia ventana (vease figura 17.10). Se copia-
Programacidn de bases de datos con Visual Basic .NET
r6n del CD-ROM 10s archivos de una base de datos tipo, poniendo en marcha un
servicio Windows que ser6 el que atienda las solicitudes de conexi6n.
Requutos de Espaclo
L401urnen C\Necesarios 1 U l G B Disponibies 28 42GB
+?@dancedReplication 9 0 1 1 1
Herramientas de Configuracion
r3ce en curso
Oracle Intelligent agent pendiente
fl
fl
v
Tennban&Creaci&tUeBasede~os
Creaaon 6e ba3e de datos donica en curso
__ - - __ ___
Para poder conectar con una cierta base de datos Oracle, es indispensable cono-
cer el nombre del servicio. Este se define en el momento de la creacion en el servi-
dor, siendo necesaria tambien una definici6n en 10s clientes. Nuestra base de datos
17. Acceso a Oracle desde Visual Basic .NET
08 del Ststema O p r a b v o
Cada base de datos cuenta con una serie de esquemas en 10s que se alojan 10s
distintos elementos, como tablas, vistas o procedimientos almacenados. Existe un
esquema por defecto, scott, que hemos usado en todos 10s ejemplos de 10s capi-
tulos previos en 10s que se utilizaba la base de datos Oracle creada en el tercer ca-
pitulo. Puede crear su propio esquema y personalizarlo, si no quiere emplear 4ste.
servidor. Por ello es necesario instalar en cada ordenador cliente el software que
facilite el fabricante del RDBMS, en este caso el software cliente de Oracle9i.
Con algunos RDBMS, como es el caso de SQL Server, basta con instalar el soft-
ware cliente para, desde una aplicacGn, conectar con una base de datos que se en-
cuentra en el servidor. Para ello ese cliente debe indicar el nombre o direcci6n del
ordenador que actua como servidor, asi como la base de datos que se desea abrir.
Estos datos corresponden con 10s parimetros Data Source e Inicial Catalog
de la cadena de conexi6n.
Sin embargo, a1 usar Oracle el cliente no tiene porque conocer ni el servidor
donde se ejecuta el RDBMS ni la base de datos, el valor asignado a1 parimetro Da-
ta Source es el nombre de servicio local con el que se conoce a la base de datos.
Ese nombre de servicio hay que definirlo, usando para ello el Asistente de Confi-
guracion de Red de Oracle que se instala como parte del software cliente. Este pro-
ceso se describi6 en el sexto capitulo, puede recurrir a 61 para recordarlo.
cuando haga falta. Nuestra aplicaci6n usaria 10s objetos de este proveedor, segun
se ha descrito en 10s capitulos de la segunda parte, facilitando en la cadena de CO-
nexi6n no el nombre del servidor RDBMS O del servicio remoto, sin0 el nombre de
servicio local que ha sido definido para acceder a esa base de datos. Adem6s pue-
de ser necesario facilitar el nombre de esquema/usuario, por ejemplo S c o t t , y la
clave de acceso correspondiente.
Con esto ya tendria su aplicaci6n Visual Basic .NET, funcionando sobre Windows
y accediendo a un RDBMS Oracle9i, sin importar que 6ste se ejecute tambi6n sobre
Windows o cualquier otro sistema operativo. Como puede ver, el proceso para ac-
ceder a la base de datos mas usada desde el lenguaje de programaci6n m6s popu-
lar no es demasiado complejo.
A1 operar sobre sistemas RDBMS, una parte de 10s origenes de datos que hemos
usado en capitulos previos lo son, es habitual utilizar transacciones que aseguren
la integridad de 10s datos, especialmente cuando se actua sobre multiples tablas.
En ninguno de 10s ejemplos propuestos hasta ahora nos hemos ocupado de las
transacciones, dejando el aseguramiento de esa integridad en manos de ADO.NET
y el RDBMS con el que se conectaba. En ocasiones, sin embargo, puede ser precis0
un control explicito del inicio y fin de la transaccibn, momento en el cual necesita-
remos emplear el objeto Transaction del proveedor adecuado tal y como se ex-
plica en 10s puntos siguientes.
Todos 10s sistemas RDBMS considerados como tales, Oracle y SQL Server son
dos ejemplos, conternplan el us0 explicito de transacciones. Una transacci6n asegu-
ra que todas las operaciones efectuadas en su bmbito, desde que se inicia hasta que
se cierra, se ejecutan de forma satisfactoria o no se ejecuta ninguna de ellas. Esto nos
garantiza la integridad de la informacih almacenada en la base de datos.
Imagine que, en una aplicaci6n Visual Basic .NET, codifica una serie de adapta-
dores de datos y DataSet para actuar sobre dos tablas: una que contiene encabe-
zados de factura y otra que almacena las filas de detalle. A1 efectuar parte de la
actualizacih, luego de ejecutar el m6todo Update ( ) del primer adaptador que,
18. Control d e transacciones
Observe que a1 final del m6todo no se utiliza una sentencia COMMIT, que seria
lo habitual para confirmar la operacion, sino ROLLBACK, de tal manera que las dos
Programacidn de bases de datos con V i s u a l Basic .NET
>
.........____....... _.__
~ . ......._
~ . _ _..-.._t.,_...I_._ . ......._..._
.^__... _ ~ _ ^ _
Para crear una transaccion asociada a una cierta conexion, como puede dedu-
cirse de 10s miembros existentes en la interfaz IDbTransaction, bastaria con
asignar a la propiedad Connection la referencia a la conexi6n. Una alternativa es
emplear el metodo BeginTransaction ( ) de la interfaz IDbConnection, im-
plementado en el objeto Connection de cada proveedor.
Ese objeto tiene que asociarse tambien con cada uno de 10s comandos que va-
yan a ser ejecutados y que se desea que queden bajo el dmbito de la transaccion.
Con este fin, en la interfaz IDbConnection hay definida una propiedad llamada
Transaction.
Creada la transaccion y enlazada tanto con la conexion como con 10s comandos,
usariamos el metodo Commit ( ) o Rollback ( 1, tras ejecutar todas las operacio-
nes de actualizacion, para confirmar o revocar la transaccion y, por tanto, todas
las operaciones ejecutadas durante su tiempo de vida.
8 - p Debug - '3@*33-.
1 : x
En principio no existe ningun vinculo entre 10s elementos de interfaz y 10s com-
ponentes de acceso a datos, vinculo que se establecer6 a1 pulsar el b o t h Seleccio-
nar. Este ejecuta el c6digo siguiente:
DataViewRowState.CurrentRows)
18. Control de transacciones
I g L i b r o s . Datasource = V i s t a
E n d Sub
B y V a l e As S y ~ t e m . E v t ? n t A r g s ) H a n d l e s b t n E l i m i n a r . C l i c k
Dim I n d F i l a As I n t e g e r
While V i s t d . C o u n t > 0
Virta(O).Delete()
End W h i l e
sq De
T r a n s a c c i o n . Commit ( )
Else '
Transaccion.Rollback ( )
E n d If
DsLibrosl.Clear()
Prograrnacidn de bases de datos con Visual Basic .NET
Sqlconnectionl .Close i )
End Sub
e bloqueo y actualizacion
A la hora de codificar una aplicacidn en la que van a obtenerse datos que, pos-
teriormente, deben ser actualizados, hay que elegir una politica de bloqueo y de
19. Resolucion de problemas de concurrencia
La politica de bloqueo optimista s610 bloquea las filas que van a ser modifica-
das o eliminadas y s610 en el momento de la actualizaci6n. Asi, en caso de que un
programa, como 10s usados a mod0 de ejemplo en capitulos previos, recupere una
lista de 10s titulos existentes en la tabla L i b r o s , esto no implicar6 que ningun otro
cliente pueda obtener esos mismos datos. No es necesario mantener una conexi6n
continua con el servidor, ya que el bloqueo se estableceria s610 en el momento de
ejecutar la sentencia UPDATE, no a1 seleccionar datos. El bloqueo optimista tiene el
problema antes planteado: ya que varios usuarios pueden acceder a las mismas fi-
las, hay que controlar la posibilidad de que dos o m6s de ellos efectuen cambios en
la misma fila. ADO.NET nos facilita 10s eventos y excepciones necesarias para ello.
En cuanto a la politica de el ultimo gana, es tan simple como asumir que en la ba-
se de datos s610 permanecer6n 10s datos que se escriban en ultimo lugar, es decir,
si varios usuarios modifican una misma fila, se perderAn todos 10s cambios excep-
to 10s del ultimo en enviarlos a1 RDBMS. Como se decia antes, suele ser una opci6n
inaceptable en la mayoria de 10s casos.
- ~ I_ _ _
Veamos c6mo aprovechar el evento RowUpda ted para ofrecer informacih so-
bre el proceso de actualizaci6n, aunque sin resolver el problema puesto que los
cambios efectuados por el usuario que no se hayan podido escribir en el origen se
perderan, a1 menos en este primer acercamiento a la soluci6n final.
Partimos disefiando un formulario como el que aparece en la figura 19.1, con un
DataGrid y un b o t h como unicos elementos de interfaz. En la parte inferior del
diseiiador puede ver la conexibn, adaptador y conjunto de datos, generados con el
Explorador de servidores. Vinculamos el DataGrid con la unica tabla del DataSet.
A1 abrirse el formulario se ejecutara la sentencia SqlDataAdapterl. Fill (ds-
Librosl, "Libros"),mostrando asi las filas de la tabla en la cuadricula desde
un primer momento.
Cuando se pulse el bot6nActualizar procederemos a llamar a1 metodo Update ( )
del adaptador, refrescando el contenido del DataSet para obtener 10s cambios
que pudiesen haberse ejecutado desde otros puestos:
I
I _ r
s1.L
nrchivo Edition Yer Proyecto enmar Depurar Datos Herrarmentas Ventana Aygda
- _ 1
-.- - - __
t1rto- I/ I
Handles SqlDataAdapter1.RowUpdated
e.Status = UpdateStatus.SKipCurrentRow
End I f
End Sub
Dim M e n s a j e As String = ~
scribir cambios?", -
MessaqeBoxButtons.YesNo) = DialogResult.Yes Then
DsLibrosl.Merge(DatosActuales, True1
SqlDataAdapterl.Update(DsLibrosl.Libros)
Prograrnacidn de bases de datos con Visual Basic .NET
E n d If
E n d Sub
Observe que se muestra tan s610 el valor de la columna Auto r, asumiendo que,
para realizar pruebas, va a modificarse esa columna y no otra. En la prActica, en
lugar de este simple mensaje seria mucho mAs adecuado preparar un formulario
en el que el usuario pudiese ver todos 10s valores que el ha introducido y 10s que
hay en la base de datos actualmente, pudiendo elegir que quiere hacer.
Tambien debe tenerse en cuenta que este metodo, a1 ser invocado desde el me-
todo RowUpda te, se ejecuta asumiendo que va a pulsarse el b o t h Actualizar tras
modificar cada fila. Esto no tiene necesariamente que ser asi, ya que el usuario po-
dria modificar varias filas. Podria automatizarse la llamada a1 metodo Update ( )
del adaptador cada vez que se detectase un cambio de fila comprobando que en
ella se han efectuado cambios. Otra posibilidad es no usar el evento Rowupdate
sin0 interceptar el evento DBConcurrencyException a1 llamar a1 metodo Upda-
te ( ) . Si &te se genera, podriamos recorrer el conjunto de filas que tienen un error
y mostrarlas todas a1 usuario de una sola vez, en lugar de consultar una a una.
I/ Valor actual='Francisco Charte Ojeda', Valor original='FranciscoCharte Ortega', Valor propuesto='Francisco Charte'
/I
l
L
W
I1
..*..,..,*'
.,. ..*.~
.'.,"~.... a;:? .
.
x
,*: . '~._.
'
~.< .. '
L,' % .. ' .
Cuando se ejecuta un comando de seleccidn de datos, ya sea obteniendo un Da-
t a R e a d e r o bien mediante un adaptador para generar un D a t a S e t , siempre ob-
tenemos un conjunto de filas predefinidas en las tablas de la base de datos y con
valores que est6n almacenados en ellas. En ocasiones, sin embargo, pueden ser ne-
cesarios datos adicionales que pueden calcularse a partir de 10s datos de las co-
lumnas, no siendo 16gico afiadir nuevas columnas en las tablas de la base de datos
para almacenarlos.
Suponga que necesita mostrar en un D a t a G r i d el titulo de cada libro, el autor,
el precio, el IVA y el precio neto. En la tabla L i b r o s tan s610 existen las tres pri-
meras columnas, per0 no el IVA o el precio neto. No tiene sentido aiiadir esas co-
lumnas a las tablas de la base de datos, ya que ocuparian un espacio innecesario al
poder calcular sus valores.
En este capitulo ver6 c6mo puede definir esas columnas calculadas, ya sea en la
propia sentencia SQL o aiiadiendo una columna a1 D a t a T a b l e , para evitar tener
que calcular y aiiadir esos valores manualmente, mediante c6digo.
spwfiguelainsmraonSelectde59Lo~lcedCeneradwdecawltaspxaB~
rafiramentela ccrsulta
de maltas...
Consulte la informacion de referencia del RDBMS que este usando para saber
que operadores y funciones puede emplear en una sentencia de seleccion para
crear columnas calculadas.
Como ya sabe, 10s objetos DataTable disponen de una coleccibn, accesible me-
diante la propiedad Columns, compuesta de objetos Datacolumn, cada uno de
10s cuales representa a una columna recuperada de las tablas del origen de datos.
En multiples ejemplos hemos recorrido esa colecci6n para mostrar todas las colum-
nas de una tabla o conocer sus atributos.
Lo mbs interesante, es que la colecci6n a la que apunta Columns no es estbtica,
siendo posible afiadir nuevos objetos Datacolumn segun se necesite. AdemAs, esos
nuevos Datacolumn no tienen necesariamente que representar a una columna de
la base de datos, pudiendo, en su lugar, alojar una expresi6n.
at
A1 crear un Da t acolumn podemos usar distintos constructores sobrecargados
que aceptan diferentes listas de par5metros. Con ellos es posible crear una nueva
columna sin establecer propiedad alguna o bien, por el contrario, asignar valor a
las mbs relevantes. Las propiedades que mbs nos interesarbn, en este caso, son las
siguientes:
Programacidn de bases de datos con Visual Basic .NET
tablas que lo componen, o sus columnas, sino que tambien podemos introducir
cambios. Ademas, esos cambios se traducen automhticamente en modificaciones a
la clase derivada de DataSet, con lo que las nuevas columnas aparecerian como
propiedades adicionales de esta.
Partiendo del anterior, d6 10s pasos siguientes para ver un sencillo ejemplo:
0 Elimine la sentencia introducida en el punto anterior con la que se creaba el
Datacolumn con el precio neto.
0 Haga clic con el b o t h secundario del rat6n sobre el DataSet,en el diseiiador
de formularios, y elija la opci6n Ver esquema. Debe encontrarse en el dise-
iiador de esquemas (vkase figura 20.4).
Pulse en la ultima fila de la tabla, que aparece como un recuadro en el dise-
fiador, e introduzca directamente el nombre y tipo. Tambikn puede escribir
y seleccionar esos datos en la ventana Propiedades.
0 Escriba en la propiedad Expression la expresi6n de calculo, en este caso
P re c io + IVA.
brchivo kddo6n yer P_royecto Cenerar Depurar Ezquerna Herramlentas VeDtana Ayuda
Libros (Lrbros)
Titulo string (Predetermmado)
Autor string ewnt (Predetermmado)
PEClD decimal
IVA decimal
0 IDLibro int (Predetermmado)
b Neto decimal
*
Precio+IVA
(Predetermmado)
(Predeterminado)
(Coleccion)
0
Net0
(Predeterrnmado)
11 ReadOdY true
I1
,/ SubsbtL-tl5#GrOup
decimal
I w=
I 0 DataSet 8 XML
-_ --
--_ __ -
LlStO I t I I,
Figura 20.4. Modificarnos el esquema usando la ventana Propiedades
A1 compilar y ejecutar el programa ver6 que obtiene exactamente el mismo re-
sultado que tenia en la figura 20.3, con la diferencia de que ahora no ha tenido que
escribir c6digo alguno. Aparte est6 la ventaja de que la nueva columna aparece co-
mo una propiedad de d s l i b r o s , de tal manera que el editor de c6digo la muestra
como un elemento m6s. Esta ventaja no la teniamos a1 crear el Datacolumn me-
diante c6digo.
F i k l i c : I s = Forml
InhrLirc: System.Windows.Forms.Form
P L ~ -tTc
, F o r m l ~ L o a d ( E ; ~ ~ ’sender
~l Jz System.Ob>ect, E
SqlDataAdapterl . F i l l (DsLibrosl, "Libras")
rj I
a Item
a ItemArray
a IVA
+ RelectChanger
aRowError a
a Rowstate I-.
Para empezar, tendremos que aiiadir a una de nuestras bases de datos una nue-
va columna, en la tabla L i b r o s , para almacenar la portada. Ya sabe que puede
21. Almacenamiento y recuperacidn de imagenes
modificar la estructura de las tablas directamente desde Visual Studio .NET, por
lo que no necesita recurrir a herramientas especificas del RDBMS.
En este caso vamos a tomar, una vez m6s, la tabla Libros de SQL Server, aiia-
dikndole, como se aprecia en la figura 21.1, una columna llamada Portada de tip0
image. Permitiremos 10s valores nulos. De hecho, a1 tener ya la tabla una serie de
filas, el valor original de la columna Portada ser6 DBNull en todas ellas. Si utili-
za las Visual Database Tools para editar el contenido de la tabla, o incluso el Adminis-
trador corporativo, ver6 que la columna Portada aparece siempre como <Binario>
(v4ase figura 21.2), no siendo posible ni ver su contenido ni modificarlo. La unica
opcion, por tanto, es crear un programa a medida que facilite esas operaciones.
iarchar 50 v
varchar 50
Columnas
Descripct6n
Valor predeterminado
Formula
E l R JP 13
.sto
-
-
w
il ...
dbo.libros :l a N5PIRON.Llbror) I
IDLibro IISBN I Titulo I Autor IEditorial I Precio
1-893115-94-1 User Interface Des Joel Spolsky 3 31
84-415.1136-5 SOL Server 2000 Francisco Charte 0 1 10.75
84-4 15-1324-4 Guia prictica para I Francisco Charte 0 1 10,75
84-415-1392-9 Programaobncon \ Francisco Charte 1 39
84-415-1376-7 Prograrnacioncon \ Francisco Chartella I 40
84-415-1351-1 Prograrnacioncon \ Francisco Charte 1 39
84-415-1290-6 Guia prktlca para I Francisco Charte 1 10,75
84-415-1291-4 Guia prbctica para I Francisco Charte I 10,52
84-415-1261-2 Prograrnacioncon [ Francisco Charte I 37,26
84-415-125-8 Guia practca para I FrancrscoCharte 1 lo, 52
84-415-1230-2 Manual avanzado E Francisco Charte 1 21,04
84-415-1202-7 Guia prdctica para I Francisco ChartelP 1 10,52
84-4 I 5-1I 32-2 Guia prbcttca para I Francisco Charte I 10,52
84-415-1 145-4 Introduccdn a la pi Francmo Charte I 24,04
84-7615-234-5 Manual del microprr Chris H.Pappas&Wi 2 40
0-471-37523-3 Assembly Language Jeff Dunternann 1 60,5
P u b l i c P r o p e r t y Portada As B y t e 0
Get
Tr Y
R e t u r n CType(Me(Me.tableLibros.PortadaColumr~),ByteO)
C a t c h e As I n v a l l d C a s t E x c e p t l o n
T h r o w N e w S t r o n g T y p i r ~ q E x c e . p t i o n( -
"Nc s e F u e d e o b t e r i e r e l valor p o r q u e e s DBNull.", e )
End Try
End Get
Set
M e j Me. t abl e l i b r o s . Port a d a C o l urnn ) = L'alue
End Set
End P r o p e r t y
21. Almacenamiento y recuperacidn de imdgenes
Libros (Libros)
IDLibro int
ISBN string
Tdulo string (Predeterrnmado)
Autor rtnng fixed
Editorial int (Predeterrninado)
de datcs de esk d m t o
,
. . , ' . .. ''I
Arthvo Edition rer Proyecto Generar Depurar Datgs Herramlentas VeEtana Aygda
Debug - JrY*33-.
h DataFormLvb [Diseiio]* I I
: .i:t ) 3, .......... . . . . . . . . . . . . . . . . . . .
DpenFileDialog1
CddExtem;,On True
CkeckFileEusts True
CheckPathEasts True
CefaultExt
Dereferenceiinks True
I
grlficos I *.bm
XnctialDrectw
Modifiers Friend
Multirded False
ReadOnlyChecked False
RestoreDrector, False
5howHelp False
ShOwReadOnly False
Title
ialidateNam True
,Itado, a
lj !I
Figura 21.4. Aspect0 del formulario tras introducir el P i c t u r e B o x y el B u t t o n
o b j d s l i b r o s , " L i b r o s " ) . P o s i t i o n t 1 ). T o s t r i n g -I
" d e ' I ) t M e . B i n d i n g C o n t e x t (objdsLibros, -
" L i b r o s " ) .Count . T o S t r i n q )
D i m P o s i c i o n = B i n d i r l g C o n t e x t (obldsLibros,
"Libros") .Position
I f N o t ob]dsLibros.Libros(Pesiciori).IsPortadaNull Then
0
E i c t u r e B rxl . C r e a t e G L a r h i c - ( ) .r ’ l e a r ( c o l o r .B l a c k )
End If
End Sub
Si ejecuta el programa tras introducir estos cambios, podrb navegar por las filas
de datos y observar que el P i c t u r e B o x siempre aparece como una superficie ne-
gra. Es logico, ya que ninguno de 10s libros cuenta actualmente con una portada en
la base de datos.
1
I _ _ _ _ - _ _ I _ _ _ -
Para llegar a tener alguna imagen en la base de datos, es nuestro objetivo, ten-
dremos que responder a1 evento C l i c k del b o t h que hay bajo el P i c t u r e B o x
con dos fines: mostrar la imagen seleccionada en el P i c t u r e B o x , simplemente a
mod0 de informacih de retorno porque ello no indica que la imagen exista en la
base de datos, y asignar dicha imagen a la columna P o r t a d a de la actual fila de
datos.
La clase Image cuenta con un metodo F r o m F i l e ( ) capaz de recuperar la ima-
gen del archivo y mostrarla en el P i c t u r e B o x . Los Datacolumn, por el contrario,
no disponen de un metodo similar. No podemos, sin mbs, asignar un nombre de
archivo a la columna P o r t a d a . Ya sabemos que su tipo es B y t e ( ) . Por lo tanto,
tendremos que recuperar la imagen en memoria, como si fuese una secuencia de
bytes, y despues asignarla a P o r t a d a .
El metodo correspondiente a1 evento C l i c k quedaria tal y como se muestra a
continuacion:
P i c t u r e B o x l . I m a g e = Irnage.FrornFile(OpenFileDia1ogl.FlleName)
Di ivo. Len
Ar .Read ( I r n a g e n , ivo.L e n g t h )
Archivo. C l o s e ( ) ’
21. Almacenamiento y recuperacidn de imagenes
o b ] ( j s L i b r o s . Libror (Me.H i r d i r q C J n t e x t 1 ~
Para crear el proveedor ADO.NET tendrd que iniciar un nuevo proyecto Visual
Basic .NET, concretamente una Biblioteca de clases. Llamela FileSys temclient,
como se ha hecho en la figura 22.1. La biblioteca obtenida, a1 compilar el proyecto,
se llamara Filesystemclient. dll.
+ J Otros proyectos
2 SoIucmes de Visual Studio
j ApIcacion
Web ASP NET
Servoo Web Biblioteca de
ASP NET conboles Web
ljombre I FlleSystemClient
Ubuacion
como hace con 10s otros proveedores. No obstante, no tiene m& que usar la herra-
mienta s n para generar la clave y firmar el m6dulo DLL para poder hacerlo.
PU
Inherits C o r n p iricintM ; i e l . Cr
Implements I L h C on n e c t i o rl
Public Sub N e w ( )
MyBase. New ( )
End Sub
st
strDataBase = ConnectionString. S u b s t r l n g ( -
ConnectionString. IndexOf ( " = " ) + 1 )
End S u b
22. Creacidn de pvoveedores ADO.NET
Observe que la cadena de conexion se guarda, tal cual, en una de las variables
definidas a1 principio a tal efecto. A continuaci6n se extrae de ella el valor que si-
gue a1 signo =. El Linico partimetro que aceptar6 nuestro proveedor en la cadena de
conexi6n serh D a t a Source,siendo su valor el camino con el que se desea conec-
tar, por ejemplo C: \Windows.
Los partimetros establecidos con la cadena de conexibn, la propia cadena de co-
nexi6n y la base de datos, asi como el estado en el que se encuentra la conexion,
cerrada o abierta, son datos accesibles mediante propiedades definidas en IDb-
Connection y que implementaremos asi:
11
E n d Set
E n d Property
P u b l i c R e a d O n l y P r o p e r t y Databas? ( ) As S t r i n g
I m p l e m e n t s I D b C ~ r n n e t i o n . Database
Get
R e t u r n strDataBase
End Get
E n d Property
, > j .
. ~
,
, .+
~,
~
P u b l i c R e a d O n l y P r o p e r t y State ( ) As ConnectionState
I m p l e m e n t s IDbConnect o r l . S t a t e
Get
Return csState
End Get
E n d Property
I m p l e m e n t s 1D b C o n n e c t o n . C h a ng P Data b a s e
st
End Sub
End Sub
PU on CreateCommand( ) A s I D b C o m m a r l d ~
a t t- C o m m a rid
Get
Return 0
End Get
End Property
End Function
ByVal l e v e l As I s o 1 , i t i o r l L e v e l ) As I D b T r s r l s a c t i o r l
Implements I Db C o r, I, e c t i o rl . B e q i rlT r a rI .c a c t i I) n
End Function
Inherits C o m p o n e r1 t Mo d e 1 , C o mp o n e rlt
Implements I D b C o m m a n d
Private s t r C o m m a n d T e x t As String
Private c t C o m m a n d T y p e As C o m m a n d T y p e
Pr tion
Friend d f O r i g e n As D i r e c t o r y I n f o
Programacidn de bases de datos con Visual Basic .NET
Tenemos sendas variables para almacenar el tip0 y texto del comando. La va-
riable cnconnection mantendrfi un enlace entre el comando y el objeto File-
Systemclientconnection sobre el que actuarfi. Por tiltimo tenemos la variable
dfOrigen, que actuarfi como origen de datos. A1 ejecutar el comando, segun verfi
despuks, se actuar6 sobre este objeto.
Observe que dfOrigen tiene el modificador Friend,facilitando el acceso a 61
desde la clase FileSystemClientDataReader que crearemos en el punto si-
guiente.
Act0 seguido implementaremos 10s distintos constructores de la clase, en este
caso concreto tres:
Son 10s tres que podemos encontrar en 10s demfis proveedores. Como puede
ver, se limitan a guardar 10s parimetros facilitados en las variables que correspon-
den, sin efectuar ninguna comprobaci6n adicional sobre su validez.
La conexi6n y tanto el tip0 de comando como su texto son parfimetros del co-
mando que pueden ser modificados en cualquier momento, ya que no se emplean
hasta la invocaci6n a uno de 10s mktodos ExecuteXXX ( ) .
Las tres propiedades siguientes facilitan tanto la obtenci6n como modificaci6n
de esos parfimetros:
Implements I D b C o m m a n d . C o m r n a n d T e x t
Get
Re turn s t r C o mma n d T e x t
End Get
SetiByVal V a l u e As String)
strCommandText = Value
End Set
End Property
22. Creacidn d e proveedores ADO.NET
Public Property C o r ~ n e c t i o r (l ) As I D b C o n n e c t i o n ~
PU
c n C o n r s e c t i o n . State = C o r t r i e c t i o n S t a t e . O p e n Then
esos casos habria que analizar el texto del comando y, en lugar de usar directamen-
te la colecci6n facilitada por Get Fi1e Sys tem1 n fo s ( ) ,filtrar las entradas obteni-
das, por ejemplo utilizando 10s metodos GetFiles ( ) y GetDirectories ( ) en
lugar de GetFileSystemInfos ( ) .
El siguiente metodo que implementaremos sera ExecuteReader ( ) que, como
sabe, debe facilitar un objeto que implemente las interfaces IDataReader e IDa-
taRecord. Lo haremos ask
( ) A s IDataReader
onnection. Database)
PU s Function ExecuteReaderi
ByVal b e h a v i o r A s CommandBehavior) A s IDataReader -
Implements 1DbComrnand.ExecutePeader
Return ExecuteReaderO
End Function
Public Function C r e a t e P a r a m e t e r O As I D b D a t a P a r a r n e t e r -
Implements I DbCornniand . C r e a t e Pa rarnet e r
Return Nothing
End Function
End Sub
End Set
End Property
I D a t a F a r a r n e t e r C o l l e c t i o n Implements 1 D b C o r n r n a n d . P a r a r n e t e r s
Get
End Get
End Property
Public Property T r a n s a c t i o n ( ) As I D b T r a n s a c t i o n
Implements I DbComrna nd . T r a n s a c t i o n
Get
Return CType ( Nothing, T DbT r a n s a c t i o n )
End Get
Set (ByVal V a l u e As I D b T r a n s a c t i o n )
End Set
End Property
Public Property U p d a t e d R o w S o u r c e O As U p d a t e R o w S o u r c e
Implements 1 D b C o r n r n a n d . U p d a t e d R o w S o u r c e
Get
Return U p d a t e R o w S o u r c e . N o n e
End Get
Set(ByVa1 V a l u e As U p d a t e R o w S o u r c e )
End Set
End Property
End Sub
Programacidn de bases de datos con Visual Basic .NET
' t e rnC'1 1 e rl t Da t a Re ad c r
Pub1 1c C1 ass Fi 1 e Sy
Inherits ComponentModpl . C o m p o n e n t
Implements I D a t a R e a d e L
Implements I D a t a R t c o r d
Pr cs1t
Private i R o w s As Integer
Tenemos dos variables enteras, iposition e iRows, que mantendr6 la fila ac-
tual y el numero total de filas. f s cCommand almacenar6 la referencia a1 comando
asociado a este lector.
Esta clase contar6 con un unico constructor que tomar6 como par6metro la re-
ferencia al comando asociado. Asi, no podra nunca crearse un lector de datos sin
comando asociado.
stemClientCornmand)
F i l e S y s t e m I n f 0 s .L e n g t h
iPosition = -1
End Sub
forma que la primera llamada a1 metodo Read ( ) nos coloque realmente en la pri-
mera fila de datos.
El metodo Read ( ) , como se ve en el cddigo siguiente, es realmente sencillo. In-
crementamos el valor de la variable iposition y, a continuacih, devolvemos
True o False dependiendo de que queden o no mas filas de datos. Para ello com-
paramos iPosition con iRows.
1E.S l t l ) I , += 1
End Function
Una vez que estamos colocados en una fila de datos, el paso siguiente serA recu-
perar el valor que almacena cada una de sus columnas. Con este fin tendremos que
implementar dos versiones diferentes de la propiedad 1tern. La primera tomara
como parametro el indice de la columna, mientras que la segunda recibirb, en lu-
gar del indice, el nombre de la columna.
Ninguno de 10s dos metodos accede directamente a la lista devuelta por Get-
FileSystemInfos ( ) , sino que utilizan el metodo GetValue ( ) de la propia cla-
se FileSys temClientDataReader.Esta siempre toma como parametro el indice
de la columna cuyo valor quiere obtenerse. Puesto que en la segunda versidn des-
conocemos dicho indice, lo que tenemos es el nombre de la columna, lo recupera-
mos mediante el metodo Getordinal ( ) .
Return GetValue(GetOrdina1 ( n a m e ))
End Get
End Property
Programacion de bases de datos con Visual Basic .NET
Para facilitar a las dos propiedades anteriores el indice o nombre de una colum-
na, con el fin de obtener su valor, primer0 necesitaremos saber cuintas columnas
hay disponibles y cuiles son sus nombres. Estos datos son 10s que nos facilita la pro-
piedad Fieldcount y el m6todo GetName ( ) , que implementamos como se ve en
el c6digo siguiente:
PU
Implements 1DataRecord.FlsldCount
Get
Return 2
End Get
End Property
Como puede verse, facilitaremos tan s610 dos columnas por fila: FullName y
CreationTime, es decir, el nombre del elemento y su fecha de creaci6n. Tambien
seri util saber qu6 tip0 de dato contiene cada una de esas columnas, informaci6n
que obtendriamos con 10s dos metodos mostrados a continuaci6n:
ByVal 1 As Integer) -
cord.GetDataTypeName
End Function
Las dos versiones de la propiedad Item hacen us0 del metodo GetValue ( ) .
h e acepta como partimetro el indice de la columna a obtener, devolviendo el va-
lor que corresponda teniendo en cuenta que la fila actual de datos es iposition.
Implements 1DataRecord.GetValue
0
With f s cComma nd . d fOr 1 g e rl . Get Fi 1 e S y s t e m I r) f o s ( i ( i Po 5 1 t 1 on 1
Select Case 1
Case 0 '
Return . F u l l N
Case 1 '
Return . Creat
End Select
End With
End Function
Implements 1DataRecord.GetOrdinal
If riame = "FullNarne" Then
Return 0
Else
Return 1
End If
End Function
v a l u e s ( 0 ) = fscCornrnand.dfOrigen.GetFileSystem1nfos ( ) ~
(iPosition).FullNarne
Programacidn de bases de datos con Visual Basic .NET
values ( 1 ) = fscComrnand.dfOrigen.GetFileSysternIr~fos
( )
(iPosition).CreationTime
Return 2
End Function
Por ultimo, ya sin implementaciones titiles, debemos codificar 10s metodos mos-
trados a continuacih. Observe que gran parte de ellos son metodos GetXXX ( ) de
la interfaz I D a t a R e c o r d , metodos que recuperan el valor de una columna no con
el tip0 original, sin0 con otro especificado.
End Sub
22. Cveacidn de proveedores ADO.NET
Implements IDataRecord.(;etByte
Return 0
End Function
La ultima clase que tenemos por implementar es la que actuar6 como adapta-
dor de datos. A diferencia de las anteriores, esta clase no estar6 derivada de Corn-
ponentModel sin0 de DbDataAdapter.
Esta clase base se ocupa ya de la implementacih de gran parte de la funciona-
lidad del adaptador de datos, por lo que el trabajo que tenemos que efectuar noso-
tros es relativamente breve y fAcil.
Comenzamos, como en 10s casos anteriores, con la declaraci6n de miembros de
datos:
Public Sub N e w ( )
MyBase.New()
End Sub
ternClientCommand)
fscSelectCornmand = CornmarJd
End Sub
El resto de 10s miembros que estamos obligados a implementar son 10s que apa-
recen a continuacih, sin c6digo util:
End Set
End Property
Get
Return Nothing
End Get
Set(ByVa1 V a l u e As I D b C o m m a n d )
End Set
End Property
End Set
End Property
ByVal s t a t e m e n t T y p e As S t a t e r n e n t T y p e , ByVal t a b l e M a p p i n g -
As Da t a T a b 1eMa p p i n g ) As RowlJ pd a t i ng Eve n t A r g s
Return Nothing
End Function
End Sub
End Sub
que lo probemos, que es lo que vamos a hacer de inmediato. Sin cerrar el proyecto
del proveedor, afiada un nuevo proyecto a la soluci6n. Agregue a1 nuevo proyecto
una referencia a1 primero, para poder utilizar el proveedor simplemente impor-
tando el 6mbito FileSystemClient.
i t
0
Dim 1 e -t ir As IL 3 t s R e i A i e r
While L e c t r. h e x i ( )
Ll
End While
U N D % % m 2 0 0 2 10 12 26
- A
UND 001 03/09/2002 16 44 32
cycled 31101 12002 8 50 14
tern Volume lnfutrnation 31 /01/2002 E
1 C \mrdownld Imp 21 /03/2001 10 13 52
C \Mi rniisica 07?08/2002 17 33 51
C iWINDOW5 08/08/2002 12 08 53
Como puede ver, creamos el adaptador de datos a partir del comando previa-
mente definido. A continuaci6n creamos el DataSet y lo llenamos con el metodo
22. Creacidn de proveedores Al3O.NET
Fill ( ) del adaptador, como hariamos en cualquier otro caso. Por ultimo, vincu-
lamos el D a t a S e t con el D a t a G r i d , obteniendo el resultado que se puede ver en
la figura 22.4.
el elemento Data Access Aplication Block, tal como se aprecia en la figura 23.1. El
archivo no llega a1 megabyte, por lo que su descarga es relativamente rfipida.
--
http Ilwwwmsdn moos01
supparted:
04/16/2002
NO
can aasily be used as a building black in your own NET
1 Data Access and Databases
1 Graphics and Multimedia
, application. &Download
Docunientation
1 Messaging and Collaboration ~
%!DISCUSSin NewSarouPs
1 NET Development
I
1 NET Enterprise Sewers
1 NET Framework ~
Figura 23.1. Seccion de MSDN donde se encuentra Data Access Application Block
El paquete obtenido es autoinstalable, por lo que bastar6 con hacer doble clic
sobre 61 para poner en marcha el proceso de instalacidn en nuestro sistema. Acep-
tamos la licencia de uso, establecemos el camino de destino (v6ase figura 23.2) y
pulsamos el b o t h Next hasta poner en marcha el proceso de copia de archivos.
La instalacidn no facilita el ensamblado en formato compilado, ni lo registra co-
mo ensamblado cornpartido, simplemente copia en la carpeta indicada el cddigo
fuente, tanto Visual Basic como C#, y la documentacidn, facilitada en un archivo de
ayuda de Windows. T a m b i h se crea en el menu del boton Inicio una carpeta, lla-
mada Microsoft Applications Block for .NET, que facilita el acceso a1 cddigo de es-
tos bloques de aplicacidn, 10s ejemplos y la documentacidn, segun se aprecia en el
detalle de la figura 23.3.
Programacidn de bases de datos con V i s u a l Basic .NET
I-
..
The nslaller w l nslall Merosdt Data Access Apdicatan Block Iw NET to the Idwngloldar
To instdl 111 this fd& ckck 'Next" To instdl to a &hnnt foMer enter 1 bebw a chck "Browd'
Eolder
C Urchwos de programa\MicrosoftApplication Blocks for NET\Dala Bjwse
Qisk Cost
Instal Microsoft Data Access Application Block foi NET fw yoursetf, or for anyone wha uses ths
cqutei
OEvwvone
@Just me
Los metodos de ayuda definidos en este paquete de c6digo son utiles para tra-
bajar con SQL Server, no siendo aplicables al resto de proveedores .NET. Al
disponer del codigo fuente, sin embargo, seria relativamente facil adaptarlo
para operar con el proveedor que nos interese.
Corn nsarnblado
Para poder utilizar este c6digo de ayuda, lo primer0 que tenemos que hacer es
compilarlo para generar el correspondiente ensamblado. Abra el elemento Data
Access Application Block del menu antes indicado. Da igual que use el c6digo Vi-
sual Basic .NET o el c6digo C#, ya que el ensamblado obtenido podr6 ser utilizado
indistintamente.
Se abrir6 Visual Studio .NET con el proyecto elegido. Pulse la combinaci6n de
teclas Control-Mayh-B, o bien elija la opci6n GeneraPGenerar solucion, para
compilar el proyecto y obtener el correspondiente m6dulo DLL. Puede cerrar el
proyecto y el entorno de Visual Studio .NET si lo desea. En este momento tenemos
23. Application Blocks para ADO.NET
Todos 10s metodos del ensamblado que hemos obtenido aparecen como meto-
dos compartidos, o estdticos, dentro de estas dos clases: SqlHelper y SqlHelper-
Parametercache, resultando especialmente interesantes 10s de la primera. Estos
son 10s siguientes:
La diferencia que hay entre estos mktodos y algunos de 10s existentes en un ob-
jet0 Command con el mismo nombre, es que &tos aceptan una cadena de conexion,
una cadena con el comando y devuelven el resultado, sin tener que crear objetos
intermedios como el adaptador de datos o el objeto Connection.
Por su parte, 10s mktodos de SqlHelperparameterCache tienen el objetivo
de facilitar el almacenamiento de par6metros empleados con consultas y procedi-
mientos almacenados.
-___I_.- ~
--.I - ~ - ~ _
-I___
~_ _~ _ -_ ~- ~ ~
Para usar estos metodos desde una aplicacion propia, lo primer0 que tenemos
que hacer es agregar una referencia a1 ensamblado Microsoft .Application-
Blocks. Data. dll.Para ello seleccione la opci6n Agregar referencia del proyec-
to y, ya que no se trata de un ensamblado compartido que se encuentre registrado
en la GAC, pulse el b o t h Examinar para localizar y aiiadir el ensamblado como se
ha hecho en la figura 23.4.
En caso de que vaya a usar 10s mktodos de SqlHelper y SqlHelperParame-
tercache en multiples proyectos, quiz6 le convenga instalar el ensamblado en la
GAC abrikndolo en Visual Studio y aiiadikndole una clave para firmarlo con un
identificador unico. En este caso el ensamblado apareceri en la lista de la p6gina
.NET y podr6 afiadirlo directamente a sus proyectos, sin necesidad de localizar el
m6dulo DLL.
Programacidn de bases de datos con Visual Basic .NET
~~ ~~ ~
. ~ ~.
CRVsPackageLib 1.0.0.0 C:\Archnos de prograrna\Arc...
.
CrystalDeC~~~Cms.CrystalRepO.,9.1.3300.0 C:\Archivos de prograrna\Arc., .
CrystalDecisions ReportSource 9.1.3300.0 C:\Archivor de prograrna\Arc ...
CrystalDecisions .Shared 9.1.3300.0 C:\Archivos de prograrna\Arc...
CrystalDecsions.Web 9.1.3300.0 C:\Archivos de prograrna\Arc ...
CrystalDecmns. M d o w s . F u . ,, 9.1.3300.0 C:\ArchvosdeprogramalArc ...
CrystalEnterpraeLib 1.0.0.0 C:\Archivos de progrma\Arc ...
Cryrtallnl'o5toreLib 1.0.0.0 C:\Archvos de prograrna\Arc...
CrystalKeyCodeLib 1.0.0.0 C:\Archivos de prograrna\Arc.. .
TrvCtaIPIiinmMnrl h I n nn r,lArrhlun. rlr nrnnrnmil\irr "
~ o w o n e n t e sselecclonados:
___ ._.-_
l ^ _ _ _ _ _ _ _ l . - ~ ~ ~ ~ ~ ~ . -
DataGridl.DataSource = SqlHelper.ExecuteDataset( ~
Aunque en este caso se han usado cadenas de caracteres para definir el origen
de datos y el comando, tambien pueden emplearse objetos S q l c o n n e c t i o n
y SqlCommand en caso de que 10s hubiesemos creado con anterioridad.
23. Application Blocks para A D O N E T
GAC Global Assembly Cache Deposit0 donde se almacenan todos 10s en-
samblados compartidos en la plataforma .NET.
HTML HyperText Markup Lenguaje para el diseAo de documentos que
Language se publican en lo quese conoce coloquialmen-
te como Web.
HTTP Hypertext Transfer Protocolo de transferencia de documentos
Protocol HTML.
JDBC Java Database Mecanismo de acceso a datos utilizado en el
Connectivity leng uaj e Java.
LDAP Lightweight Directory Protocolo estandar para el acceso a servicios
Access Protocol de directorio.
MDAC Microsoft Data Componentes de acceso a datos de Microsoft.
Access Components Un paquete compuesto de bibliotecas de en-
lace dinamico conteniendo servicios ADO y
proveedores OLE DB.
MSDE Microsoft Data Engine Motor de base de datos compatible con SQL
Server.
MSlL Microsoft Intermediate Lenguaje en el que generan codigo todos 10s
Language compiladores de lenguajes .NET.
ODBC Open Database Mecanismo estandar de acceso a datos, pre-
Connectivity vio a DAO, ADO y ADO.NET.
OLE DB Object Linking & Tecnologia para la creacion y us0 de controla-
Embedding Database dores de acceso a distintos origenes de datos.
PK Primary Key Clave primaria en una tabla.
PLISQL Procedural Lenguaje procedural derivado de SQL que se
Language/Structured emplea en las bases de datos Oracle.
Query Language
RDBMS Relational Database DBMS relacional, actualmente la mayoria de
Management System ellos lo son.
SAX Simple API for XML Conjunto de funciones simples para el trata-
miento de documentos XML.
SGBD Sistema gestor de Equivalente a DBMS.
bases de datos
SGML Standarized General Lenguaje estandar de marcas del que se deri-
Markup Language van otros, como HTML o XML.
SQL Structured Query Lenguaje utilizado en la practica totalidad de
Language 10s RDBMS para la seleccion y manipulacion
de datos y sus estructuras.
Este libro incorpora un CD-ROM en el que podr6 encontrar todos 10s ejemplos
que se han descrito en sus capitulos, facilit6ndole asi el acceso a todo el c6digo sin
necesidad de tener que teclearlo personalmente. En la carpeta E j emplos encon-
trar6 una subcarpeta por cada capitulo, en cuyo interior se ha creado una carpeta
para cada ejemplo de ese capitulo en concreto.
Adem6s del c6digo fuente de 10s proyectos tambien se entregan kstos ya compi-
lados. Estos, no obstante, no pueden ser ejecutados directamente desde Windows
a menos que se tenga instalada la plataforma Microsoft .NET, entregada t a m b i h en
el CD-ROM. En caso de que tenga instalado en su sistema el product0 Visual Stu-
dio .NET en alguna de sus versiones, ya cuenta tambikn con la plataforma .NET.
En cualquier caso, debe tener en cuenta que 10s proyectos se entregan como sim-
ples ejemplos, nunca como aplicaciones de us0 final, por lo que no se otorga garan-
tia alguna ni soporte de su funcionamiento. Nuestro objetivo es facilitarle c6digo
sobre el que pueda hacer pruebas y desarrollar sus propios proyectos.
Pcrtam No(otrla¶
-nirertnrin
.. - -.-. .-
Artkubs Llbmd RsCurOS
I
Guia practica para usuarios d e Visual
Glosario ljltinios articuios y recurs05
Studio .NET
Por lo demis no es necesario ningun paso adicional para poder usar 10s ejemplos.
No olvide que para comprender las t6cnicas te6ricas es fundamental la prictica y
que, aunque se facilite el c6digo para que no tenga que introducirlo manualmente,
es importante que lo examine cuidadosamente y que lo utilice para experimentar,
introduciendo cambios y usandolo como base para sus propios ejemplos.
Tanto la editorial como el autor de este libro se ponen a disposici6n del lector
para cualquier problema que pudiera encontrar en el us0 del CD-ROM, su conteni-
do o bien el del libro que tiene en sus manos. En la web de Anaya Multimedia,
http: //www.AnayaMultimedia.corn, podri encontrar informaci6n adicional,
en caso de que la hubiera, asi como el enlace necesario para solicitar ayuda. De
igual forma, el autor mantiene una sede, llamada Torre d e Babel, en la direcci6n
http: //www.fcharte.com,con datos sobre 6ste y otros libros, articulos y des-
de donde puede ponerse en contact0 con 61 en caso de que encuentre algun tip0 de
problema.
@@IDENTITY- Transact-SQL, 250 System.Data, 154
System.Data.Common, 154
A System.Data.OleDb, 154
System.Data.OracleClient, 155
Acceptchangeso System.Data.SqlClient, 154
DataSet, 165, 261 System.Data.SqlTypes, 155
DataTable, 166 AND - SQL, 59
ACID - Glosario, 501 ANSI - Glosario, 501
Add() - DataRowCollection, 166 API - Glosario, 501
AddNew() - Dataview, 169, 276 Appendchild0 - XmlNode, 303
ADO - Glosario, 501 ASC
ADS1 - Glosario, 501 CREATE INDEX, 55
AllowDBNull - Datacolumn, 168 ORDER BY, 61
AllowDelete - Dataview, 276 ASCII - Glosario, 501
AllowEdit - DataView, 276 ASE'.NET
AllowNew - Dataview, 276 AutoPostBack, 375
ALTER - SQL, 50 DataBindO, 372
ALTER TABLE - SQL, 54 DataBinder, 372
ALTER VIEW - SQL, 56 DataList, 380
Ambitos Repeater, 380
Microsoft.Data.Odbc, 155 Attributes - XmlNode, 302
fndice alfabe'tico
DataColumnMapping - DataRowVersion -
System.Data.Common, 156 System.Data, 167
DataColumnMappingCollection - DataRowView
System.Data.Common, 156 BeginEdit(), 276
DataGrid CancelEdit(), 276
CancelCommand, 406 EndEdit(), 276
Controles, 370 System.Data, 276
DataKeyField, 376 DataSet
Editcommand, 406 Acceptchangeso, 165, 261
EditItemIndex, 406 Casesensitive, 237
Updatecommand, 406 Conceptos, 141
DataGridItem DataSetName, 164
Cells, 406 DataViewManager, 277
ItemIndex, 406 DefaultViewManager, 277
System.Windows.Forms, 406 EnforceConstraints, 168
DataKeyField - DataGrid, 376 Haschangeso, 164
DataList ReadXmlO, 165
ASP.NET, 380 ReadXmlSchema(), 165, 260
ItemTemplate, 381 Rejectchangeso, 165
DataMember - ListBox, 375 Relations, 164, 236
DataReader - Conceptos, 144 System.Data, 163
DataRelation Tables, 164, 236
ChildColumns, 169 WriteXmlO, 165, 260
ChildTable, 169 WriteXmlSchema(), 165, 260
ParentColumns, 169 XmlDataDocument, 310
ParentTable, 169 DataSetColumn -
System.Data, 169 IColumnMapping, 156
DataRelationCollection - DataSetName - DataSet, 164
System.Data, 164 DataSetTable - ITableMapping, 156
DataRow Datasource - ListBox, 372
BeginEdit(), 167 DataTable
CancelEdit(), 167 AcceptChangesO, 166
Delete(), 166 ChildRelations, 166
EndEdit(), 167 Columns, 165, 236
GetColumnsInError(), 167 Constraints, 165, 236
HasErrors, 167 Defaultview, 279
Hasversion(), 167 GetChildRows(), 286
Item, 166 NewRow(), 166
Rowstate, 166, 241 ParentRelations, 166
System.Data, 165 PrimaryKey, 165
DataRowCollection - Add(), 166 Rejectchangeso, 166
Programacidn de bases de datos con Visual Basic .NET
DROP - SQL, 50
DROP INDEX - SQL, 55
DROP TABLE - SQL, 54 Fetching - Connectionstate, 176
DROP VIEW - SQL, 56 Fieldcount - IDataRecord, 157
DSN - Glosario, 502 Fill() - IDataAdapter, 159, 239
DTD - Glosario, 502 Fillschema() - IDataAdapter, 247
Find() - Dataview, 169, 281
E FindRowsO - Dataview, 169, 281
Firstchild - XmlNode, 302
Editcommand - DataGrid, 406 FK - Glosario, 502
EditItemIndex - DataGrid, 406 FLOAT
element - XSD, 126 PLISQL, 70
ELSE SQL, 52
PLISQL, 71 float - Transact-SQL, 67
Transact-SQL, 68 FOR - PL / SQL, 71
ELSIF - PLISQL, 71 for-each - XSLT, 307
END - Transact-SQL, 68 FOREIGN KEY - SQL, 53
EndEdit() Foreignconstraint
DataRow, 167 DeleteRule, 168
DataRowView, 276 System.Data, 168
Enforceconstraints - DataSet, 168 UpdateRule, 168
EXECUTE - Transact-SQL, 95 Form - Bindingcontext, 377
ExecuteDataSetO - SqlHelper, 496 FROM - SQL, 58
ExecuteNonQuery () FromStreamO - PictureBox, 464
IDbCommand, 218
SqlHelper, 496 G
ExecuteOracleNonQuery() -
OracleCommand, 219 GAC - Glosario, 503
ExecuteOracleScalar() - GetBoolean0 - IDataRecord, 157
OracleCommand, 219 GetByte() - IDataRecord, 157
ExecuteReaderO GetChildRows() - DataTable, 286
IDbCommand, 218 GetColumnsInError() - DataRow, 167
SqlHelper, 496 GetDeleteCommand() -
Executescalar() SqlCommandBuilder, 163
IDbCommand, 218 GetElementFromRow() -
SqlHelper, 496 XmlDataDocument, 310
ExecuteXmlReader() GetFloatO - IDataRecord, 157
SqlCommand, 219 GetInsertCommand() -
SqlHelper, 496 SqlCommandBuilder, 163
Executing - Connectionstate, 176 GetOleDbSchemaTable() -
Expression - Datacolumn, 454 OleDbConnection, 202
Programacidn d e bases de datos con V i s u a l Basic .NET
IsolationLevel -
IDbTransaction, 161, 438
ITableMapping MAX() - SELECT, 62
ColumnMappings, 156 MaxLength - Datacolumn, 167
DataSetTable, 156 MDAC - Glosario, 503
SourceTable, 156 Microsoft.Data.Odbc
System.Data, 156 Ambitos, 155
ITableMappingCollection - OdbcDataAdapter, 159
System.Data, 156 OdbcDataReader, 158
Item MINO - SELECT, 62
DataRow, 166 MissingMappingAction -
DataView, 169, 276 IDataAdapter, 239
IDataRecord, 157 MissingSchemaAction -
ItemIndex - DataGridItem, 406 IDataAdapter, 239
ItemTemplate - DataList, 381 money - Transact-SQL, 67
IXPathNavigable - MoveNextO -
System.Xm1, 302 XPathNodeIterator, 306
MSDE - Glosario, 503
MSIL - Glosario, 503
OdbcDataAdapter - OracleDataReader
Microsoft.Data.Odbc, 159 GetOracleBinaryO, 158
OdbcDataReader - GetOracleNumber(), 158
Microsoft.Data.Odbc, 158 Getoraclestring(), 158
OdbcTransaction - System.Data.OracleClient, 158
System.Data.Odbc, 162 OracleTransaction -
OLE DB - Glosario, 503 System.Data.OracleClient, 162
OleDbCommand - ORDER BY
System.Data.OleDb, 162 ASC, 61
OleDbCommandBuilder - DESC, 61
System.Data.OleDb, 163 SQL, 61
OleDbConnection
GetOleDbSchemaTable(), 202 P
System.Data.OleDb, 162
OleDbDataAdapter - Parameters - IDbCommand, 217
System.Data.OleDb, 159 ParentColumns - DataRelation, 169
OleDbDataReader - ParentNode - XmlNode, 303
System.Data.OleDb, 158 ParentRelations - DataTable, 166
OleDbSchemaGuid ParentTable - DataRelation, 169
Columns, 203 PictureBox - FromStreamO, 464
Procedure-Parameters, 203 PK - Glosario, 503
Procedures, 203 PL / SQL
Table-Constraints, 203 BFILE, 70
Tables, 203 CHAR, 70
Views, 203 CREATE FUNCTION, 72
OleDbTransaction - CREATE PROCEDURE, 72
System.Data.OleDb, 162 DATE, 70
Open - Connectionstate, 176 DECIMAL, 70
OPEN - PL / SQL, 109 DECLARE, 70
Open() - IDbConnection, 161, 176 DEFAULT, 72
OR - SQL, 59 DOUBLE PRECISION, 70
OracleCommand ELSE, 71
ExecuteOracleNonQuery(), 219 ELSlF, 71
ExecuteOracleScalar(), 219 FLOAT, 70
System.Data.OracleClient, 162 FOR, 71
OracleCommandBuilder - Glosario, 503
System.Data.OracleClient, 163 IF, 71
OracleConnection - LOOP, 71
System.Data.OracleClient, 162 NATURAL, 70
OracleDataAdapter - OPEN, 109
System.Data.OracleClient, 159 POSITIVE, 70
Programacidn de bases de datos con Visual Basic .NET
XmlValidatingReader XSD
System.Xm1, 299 complexType, 125
ValidationType, 300 element, 126
XmlWriter - System.Xm1, 302 Glosario, 504
XPathDocument - XSL - Glosario, 504
System.Xml.XPath, 297 XSLT
XPathNavigator for-each, 307
Select(), 306 Glosario, 504
System.Xml.XPath, 306 template, 307
XPathNodeIterator value-of, 307
Current, 306 XslTransform -
MoveNextO, 306 System.Xml.Xs1, 298, 308
System.Xml.XPath, 306