(anaya) bases de datos con visual basic net

Todos 10s nombres propios de programas, sistemas operativos, equipos hardware, etc. que aparecen en este libro son marca

Views 191 Downloads 9 File size 16MB

Report DMCA / Copyright

DOWNLOAD FILE

Recommend stories

Citation preview

Todos 10s nombres propios de programas, sistemas operativos, equipos hardware, etc. que aparecen en este libro son marcas registradas de sus respectivas compaiiias u organizaciones.

Reservados todos 10s derechos. El contenido de esta obra esta protegido por la ley, que establece penas de prision yio multas, ademas de las correspondientes indemnizaciones por daiios y perjuicios, para quienes reprodujeren, plagiaren, distribuyeren o comunicasen publicamente, en todo o en parte, una obra literaria, artistica o cientifica, o su transformacion, interpretacion o ejecucion artistica fijada en cualquier tip0 de soporte o comunicada a traves de cualquier medio, sin la preceptiva autorizacion.

0 EDICIONES ANAYA MULTIMEDIA (GRUPO ANAYA, S.A.), 2002 Juan Ignacio Luca de Tena, 15. 28027 Madrid Deposit0 legal: M. 41.765 - 2002 ISBN: 84-415-1375-9 Printed in Spain Imprime: Artes Graficas Guemo, S.L. Febrero, 32. 28022 Madrid.

Agradecimientos ..................................................................................................................... 6

..

Introduccion

.......................................................................................................

Soluciones de acceso a datos .............................................................................................. ADONET ................................................................................................................................ Visual Studio .NET ............................................................................................................... Objetivos de este libro ......................................................................................................... Estructura del libro ............................................................................................................... Ayuda a1 lector ......................................................................................................................

.

................................................................................... 1. Terminologia y conceptos .............................................................................

Parte I Sentar las bases

Origenes de datos ................................................................................................................. Bases de datos ........................................................................................................................ DBMS y RDBMS .............................................................................................................. Arquitectura cliente/ servidor ........................................................................................... Arquitecturas n-tier .............................................................................................................. Servicios de acceso a datos ................................................................................................. Proveedores y controladores ............................................................................................. Lenguajes de comunicaci6n ................................................................................................

18 20 20 21 21 22 24

25

26 27 29 29 30 32 33 33 34

fndice de contenidos

Estructura de 10s datos ........................................................................................................ Entidades y atributos ..................................................................................................... Dominios y restricciones ............................................................................................... Identidad de una entidad .............................................................................................. Relaciones entre conjuntos de entidades ................................................................... Indices ................................................................................................................................ Vistas .................................................................................................................................. Procedimientos almacenados ....................................................................................... Normalizaci6n .................................................................................................................. Transacciones ................................................................................................................... XML .......................................................................................................................................... Resumen ..................................................................................................................................

.

2 SQL y sus dialectos

.......................................................................................

iQu6 es SQL?.......................................................................................................................... Partes de SQL ................................................................................................................... Derivados de SQL ........................................................................................................... Ejecuci6n de sentencias SQL ........................................................................................ DDL .......................................................................................................................................... Creaci6n de una base de datos ..................................................................................... Creaci6n de tablas ........................................................................................................... Modificaci6n y borrado de tablas ............................................................................... Otras operaciones de definici6n de datos ................................................................. DML .......................................................................................................................................... Inserci6n de datos ........................................................................................................... Recuperaci6n de datos ................................................................................................... Alias de tablas ............................................................................................................ Selecci6n de filas ........................................................................................................ Condicionales complejos .......................................................................................... Orden de las filas ....................................................................................................... Expresiones y funciones de resumen .................................................................... Agrupamiento ............................................................................................................. Enlaces entre tablas ................................................................................................... Consultas dentro de consultas ............................................................................... Actualizacibn de datos ................................................................................................... Eliminaci6n de datos ...................................................................................................... DCL ........................................................................................................................................... Derivados de SQL ................................................................................................................. Transact-SQL .................................................................................................................... Variables y tipos de datos ....................................................................................... Evaluaci6n de expresiones ...................................................................................... Condicionales y bucles ............................................................................................. Codificaci6n de procedimientos almacenados ................................................... PL / SQL ..............................................................................................................................

36 36 37 37 38 39 40 40 41 41 43 43

44 46 46 47 47 48 51 51 54 54 56 57 58 58 59 59 61 61 62 62 63 64 65 65 66 66 67 68 68 69 69

Programacidn de bases de datos con Visual Basic .NET

Variables y tipos de datos ....................................................................................... Evaluacidn de expresiones ...................................................................................... Condicionales y bucles ............................................................................................. Codificaci6n de procedimientos almacenados ................................................... Resumen ..................................................................................................................................

.

3 Origenes de datos

..........................................................................................

Origenes locales y remotos ................................................................................................. Microsoft Access ................................................................................................................... Definicion de las tablas .................................................................................................. Relaci6n entre las tablas ................................................................................................ Introducci6n de datos .................................................................................................... Simplificar la selecci6n de editorial ............................................................................ SQL Server .............................................................................................................................. Creaci6n de la base de datos ........................................................................................ Definici6n de las tablas .................................................................................................. Relacidn entre las tablas ................................................................................................ Introducci6n de datos .................................................................................................... Us0 de la base de datos de ejemplo ............................................................................ Definici6n de una vista .................................................................................................. Definir procedimientos almacenados ......................................................................... Ejecuci6n de procedimientos almacenados .............................................................. Oracle ....................................................................................................................................... Creaci6n de la base de datos ........................................................................................ Definicion de las tablas .................................................................................................. Introducci6n de datos .................................................................................................. Definici6n de una vista ................................................................................................ Definir funciones y procedimientos almacenados ................................................ Ejecuci6n de funciones y procedimientos ............................................................... InterBase ................................................................................................................................ Creaci6n de la base de datos ...................................................................................... Definicidn de las tablas ................................................................................................ Introduccidn de datos .................................................................................................. Definici6n de una vista ................................................................................................ Definir procedimientos almacenados ....................................................................... Ejecuci6n de procedimientos almacenados ............................................................ Microsoft Excel .................................................................................................................... Creaci6n de un nuevo libro ........................................................................................ Definici6n de la estructura .......................................................................................... Introducci6n de datos .................................................................................................. XML ........................................................................................................................................ Definici6n de la estructura de documento .............................................................. Creaci6n del documento XML ................................................................................... Directorio activo ..................................................................................................................

70 70 71 71 72

74 75 76 77 79 79 81 83 84 85 87 89 90 91 93 95 96 97 98 104 105 106 110 111 113 115 116 117 118 120 120 121 121 123 125 125 128 133

Acceso a1 Directorio activo ......................................................................................... Resumen ................................................................................................................................

Parte I1. ADO.NET

......................................................................................... .. 4 . Introduccion a ADO.NET .......................................................................... Objetivos del modelo ADO.NET ..................................................................................... Representach interna en XML ...................................................................................... Ausencia de cursores de datos ........................................................................................ Cursores de lectura ....................................................................................................... Soluci6n multiprop6sito .................................................................................................... Configuraci6n de 10s clientes ........................................................................................... Resumen ................................................................................................................................

.

5 Modelo de objetos

.......................................................................................

Estructura del modelo de objetos ................................................................................... Ambitos con nombre de ADO.NET ................................................................................ Interfaces para 10s proveedores ...................................................................................... Asociaci6n de columnas y tablas ............................................................................... Acceso a filas de datos ................................................................................................. Adaptadores de datos .................................................................................................. Conexiones, comandos y transacciones ................................................................... Detalles sobre 10s proveedores ........................................................................................ Otras clases comunes y especificas ........................................................................... Clases independientes del origen de datos .................................................................. Conjuntos de datos ....................................................................................................... Tablas ................................................................................................................................ Filas ................................................................................................................................... Columnas ......................................................................................................................... Restricciones ................................................................................................................... Relaciones ........................................................................................................................ Vistas de datos ............................................................................................................... Resumen ................................................................................................................................

. . al origen de datos 6 Conexion

.

........................................................................

Obtencion e instalaci6n de proveedores adicionales ................................................. D6nde obtener 10s proveedores ................................................................................. Instalaci6n del proveedor ............................................................................................ Generalidades sobre la conexi6n ..................................................................................... Cadena de conexi6n ...................................................................................................... Apertura y cierre de la conexi6n ............................................................................... Propiedades informativas ........................................................................................... Cadenas de conexi6n ..........................................................................................................

133 134

137 138 139 141 143 144 144 148 150

152 153 154 155 156 156 159 160 161 162 163 164 165 166 167 168 168 169 170

172 173 174 174 176 176 177 178 178

Programacidn de bases de datos con V i s u a l Basic .N.ET

Selecci6n del controlador ............................................................................................ Identificacibn del servidor u origen de datos ........................................................ Base de datos inicial ..................................................................................................... Parimetros de seguridad ............................................................................................ Propiedades exclusivas ................................................................................................ En la prictica ........................................................................................................................ Conexi6n con Microsoft Access ................................................................................. Conexi6n con Microsoft Excel .................................................................................... Conexi6n con SQL Server ............................................................................................ Conexi6n con InterBase ............................................................................................... Conexi6n con Oracle 8i ................................................................................................ Conexiones ODBC mediante DSN .................................................................................. Tipos de DSN ................................................................................................................. Creaci6n de un DSN ..................................................................................................... Us0 del DSN con ADO.NET ....................................................................................... Archivos UDL ...................................................................................................................... Resumen ................................................................................................................................

.

7 Informacibn de esquema de la base de datos

..........................................

iQu6 es la informaci6n de esquema? ............................................................................. Origenes OLE DB ................................................................................................................ Tabla de resultados ....................................................................................................... En la practica .................................................................................................................. Otros origenes ...................................................................................................................... En la practica .................................................................................................................. Informaci6n sobre columnas ............................................................................................ En la practica .................................................................................................................. Resumen ................................................................................................................................

.

. . de datos 8 Recuperacion

................................................................................

Generalidades sobre 10s comandos ................................................................................ Asociaci6n entre comando y conexi6n ..................................................................... Definicion del comando a ejecutar ............................................................................ Ejecuci6n del comando ................................................................................................ Lectura de 10s datos ........................................................................................................... Recuperar el contenido de una tabla ........................................................................ Varios conjuntos de datos ........................................................................................... Ejecuci6n de sentencias de selecci6n ........................................................................ Sentencias con parhmetros .......................................................................................... Recuperaci6n de un solo valor ................................................................................... Manipulacidn de datos ...................................................................................................... Otras operaciones ................................................................................................................ Recuperaci6n de una vista .........................................................................................

178 181 181 181 183 183 183 185 186 188 189 193 194 194 196 197 199

200 201 202 203 204 206 206 209 210 212

214 215 216 217 217 219 220 222 223 226 228 228 229 230

fndice de contenidos

Ejecuci6n de un procedimiento almacenado .......................................................... Resumen ................................................................................................................................

9. Conjuntos de datos

.....................................................................................

Generalidades sobre conjuntos de datos ....................................................................... Tablas y relaciones ........................................................................................................ Selecci6n de datos ......................................................................................................... Generalidades sobre adaptadores de datos ................................................................. Creaci6n de un adaptador de datos ......................................................................... Obtenci6n de 10s datos ................................................................................................. Actualizaci6n de datos ................................................................................................. En la prActica ........................................................................................................................ Recuperaci6n de datos ................................................................................................. Informaci6n de esquema ............................................................................................. Manipulaci6n de 10s datos .......................................................................................... Definici6n de conjuntos de datos .................................................................................... Creaci6n de tablas. columnas y relaciones ............................................................. Insertion de datos ......................................................................................................... Consulta de estructura y contenido .......................................................................... Almacenamiento local ........................................................................................................ Escritura de esquema y datos .................................................................................... DiffGrams ........................................................................................................................ Lectura del conjunto de datos .................................................................................... Resumen ................................................................................................................................

.

10 Relaciones y vistas

.....................................................................................

Filtrado y ordenaci6n de un DataTable ......................................................................... Generalidades sobre DataView y DataViewManager ............................................... Funcionamiento de un DataView .............................................................................. Funcionamiento de un DataViewManager ............................................................. En la pr6ctica ........................................................................................................................ Multiples vistas sobre una misma tabla .................................................................. La vista por defect0 de una tabla .............................................................................. Busqueda de datos en una vista ................................................................................ Edici6n de datos en la vista ........................................................................................ Us0 de un DataViewManager .................................................................................... Resumen ................................................................................................................................

11. XML

............................................................................................................

231 233

234 235 236 237 237 238 239 241 243 244 246 250 253 253 255 256 258 260 261 264 267

270 272 274 276 277 278 278 279 281 284 286 289

290

XML y temas relacionados ................................................................................................ 291 Breve introducci6n a XML .......................................................................................... 292 294 Definiciones de tip0 y esquemas ............................................................................... Ambitos con nombre ........................................................................................ :...........295

Programacidn de bases de datos con Visual Basic .NET

Mecanismos de manipulaci6n de documentos XML ............................................ Selecci6n de datos con XPath ..................................................................................... Transformaci6n con XSLT ........................................................................................... El Eimbito System.Xm1........................................................................................................ Lectura secuencial de documentos XML ................................................................. Manipulacibn de documentos XML con DOM ...................................................... Navegaci6n por el documento mediante XPath .................................................... Transformaci6n de documentos ................................................................................ XML y AD(l.NET ................................................................................................................ La clase XmlDataDocument ........................................................................................ Creaci6n del DataSet a partir del documento XML ............................................. Generaci6n del documento XML a partir del DataSet ......................................... Resumen ................................................................................................................................

........................................................................ 12. Capacidades de datos en Visual Studio .NET ......................................

Parte I11. Visual Studio .NET

Ediciones de Visual Studio .NET .................................................................................... Posibilidades de acceso ..................................................................................................... Productos integrados en el paquete ............................................................................... Posibilidades de disefio ..................................................................................................... Una visi6n general .............................................................................................................. Resumen ................................................................................................................................

13. Herramientas visuales de datos

...............................................................

El Explorador de servidores ............................................................................................ Definir una nueva conexi6n ........................................................................................ Registrar un nuevo servidor ....................................................................................... Apertura y cierre de conexiones ................................................................................ Creaci6n de nuevas bases de datos .......................................................................... Edici6n de datos .................................................................................................................. Navegar por las filas ..................................................................................................... Selecci6n de datos ......................................................................................................... Modificacibn, inserci6n y eliminaci6n ..................................................................... Agrupaci6n de 10s resultados .................................................................................... Edici6n de informacion de esquema .............................................................................. Creaci6n y modificaci6n de tablas ............................................................................ Disefio de vistas ............................................................................................................. Edici6n de procedimientos almacenados y funciones ......................................... Componentes de acceso a datos ...................................................................................... Preparaci6n de la conexi6n ......................................................................................... Definici6n de comandos ............................................................. :................................ Definici6n del adaptador de datos ...........................................................................

296 297 297 298 298 301 305 307 309 310 311 312 314

317 318 319 321 322 322 324 325

326 328 328 331 332 333 334 336 336 340 341 343 343 346 347 350 351 352 354

fndice de contenidos

Creaci6n del conjunto de datos ................................................................................. Diseiio de una sencilla interfaz .................................................................................. Creaci6n automtitica de componentes ........................................................................... El asistente de configuraci6n de adaptadores ....................................................... Comprobaci6n del adaptador de datos ................................................................... Generaci6n del conjunto de datos ............................................................................. Conjuntos de datos con tip0 ....................................................................................... Aun m6s simple ............................................................................................................. Resumen ................................................................................................................................

.

14 Componentes con vinculacih a datos

...................................................

Tipos de vinculaci6n .......................................................................................................... Vinculaci6n simple ........................................................................................................ Vinculaci6n con mtiltiples filas de una columna ................................................... Vinculaci6n con mtiltiples filas y columnas ........................................................... Enlace a datos en formularios Windows ...................................................................... Posici6n actual en una lista de datos ........................................................................ Control de la vinculaci6n ............................................................................................ Componentes enlazables ............................................................................................. Enlace a datos en formularios Web ................................................................................ Vinculos s610 de lectura ............................................................................................... Navegaci6n con componentes simples .................................................................... Actualizaci6n del origen .............................................................................................. Resumen ................................................................................................................................

.

15 Formularios de datos

................................................................................

El asistente para formularios Windows ........................................................................ Selecci6n del DataSet .................................................................................................... Definici6n de la conexi6n ............................................................................................ Selecci6n de 10s elementos de origen ....................................................................... Definir la relacion entre las tablas ............................................................................ Selecci6n de columnas .................................................................................................. Elegir el diseiio del formulario .................................................................................. Personalizaci6n del diseiio .......................................................................................... Antilisis del c6digo generado ..................................................................................... El asistente para formularios Web .................................................................................. Antilisis del c6digo generado ..................................................................................... Aiiadir capacidades de edici6n .................................................................................. Inserci6n de 10s enlaces de edici6n ..................................................................... Eventos y elementos de un DataGrid ................................................................. C6digo asociado a 10s eventos ............................................................................. Actualizaci6n del origen de datos ....................................................................... Resumen ................................................................................................................................

355 356 358 358 362 362 363 365 366

368 369 370 374 376 377 378 379 379 380 380 381 385 386

388 389 390 391 391 392 393 395 396 397 401 402 404 404 405 406 408 410

Prograrnacidn de bases de datos con Visual Basic .NET

...................................................... . . genCrica ..................................................................................... 16. Conexion

Parte IV.Resoluci6n de casos concretos

Interfaces genkricas ............................................................................................................ Disefio de la interfaz de usuario ..................................................................................... Implementacih de funciones .......................................................................................... Ejecucih del proyecto .......................................................................................................

.

17 Acceso a Oracle desde Visual Basic .NET

.............................................

Servidor, servicio y esquema ........................................................................................... Instalaci6n de Oracle9i ................................................................................................. Administracibn del servidor ...................................................................................... Identificacibn de servicio y esquema ....................................................................... El software cliente ............................................................................................................... Definicih del servicio ................................................................................................. Instalacih del proveedor .................................................................................................

18. Control de transacciones

..........................................................................

Raz6n de ser de las transacciones ................................................................................... Transacciones en la base de datos .................................................................................. Transacciones en Visual Basic .NET ............................................................................... Creacih del objeto Transaction ................................................................................ En la pr6ctica ..................................................................................................................

19. Resoluci6n de problemas de concurrencia

............................................

411 412 413 414 415 418

420 421 423 429 429 430 431 431

434 435 436 437 438 438

442

Politicas de bloqueo y actualizacih .............................................................................. Informaci6n de retorno durante la actualizacibn ....................................................... Un primer acercamiento .............................................................................................. Fusi6n de 10s cambios ........................................................................................................

443 444 445 447

.

450

20 Tablas con columnas calculadas

.............................................................

Columnas calculadas en la sentencia SQL .................................................................... Afiadir columnas a un DataTable ................................................................................... Creacih de un nuevo Datacolumn ......................................................................... Creaci6n en fase de disefio ..........................................................................................

451 453 453 454

.

458

21 Almacenamiento y recuperaci6n de imagenes

......................................

Afiadir una columna para la portada ............................................................................ Columnas binarias .............................................................................................................. Disefio del formulario Windows ..................................................................................... Recuperar la imagen de la base de datos ................................................................ Asignar una imagen desde un archivo ....................................................................

459 460 462 464 465

fndice de contenidos

.

......................................................

22 Creaci6n de proveedores ADO.NET Inicio del proyecto .............................................................................................................. FileSystemClientConnection ............................................................................................ FileSystemClientCommand .............................................................................................. FileSystemClientDataReader ............................................................................................ FileSystemClientDataAdapter ......................................................................................... Prueba del proveedor ......................................................................................................... Ejecuci6n de un comando ............................................................................................ Us0 del lector de datos ................................................................................................ Us0 del adaptador de datos ........................................................................................ 23. Application Blocks para ADO.NET

.......................................................

Obtenci6n de Data Access Application Blocks ............................................................ Compilaci6n del ensamblado ........................................................................................... Us0 de 10s mktodos SqlHelper ........................................................................................ Agregar una referencia a1 ensamblado .................................................................... Us0 de 10s mktodos compartidos .............................................................................. Documentaci6n adicional ..................................................................................................

........................................................................................................ B. Contenido del CD-ROM ............................................................................

A . Glosario

Us0 de 10s ejemplos ............................................................................................................ Atencion a1 lector ................................................................................................................

Indice alfabCtico

...............................................................................................

468 470 471 474 479 485 487 488 488 489

492 493 495 496 496 497 498

500

506 507 509

51 1

Independientemente de la finalidad concreta que tenga una cierta aplicacion, la necesidad de almacenar y recuperar informacion es una constante casi invariable. En ocasiones esa informacih se aloja localmente, en un soporte asociado a1 mismo ordenador en el que se ejecuta la aplicacibn, mientras que en otras lo hace de forma remota, en algun tip0 de servidor. A lo largo del tiempo, desde el nacimiento de 10s primeros lenguajes de programaci6n hasta la actualidad, 10s mecanismos utilizados para transferir la informacih desde su origen hasta la aplicacion, o viceversa, han sido diversos, si bien es cierto que en 10s ultimos afios el mas usado ha sido la base de datos. Si bien es cierto que, en un principio, lo mas importante era la posibilidad de guardar 10s datos para recuperarlos posteriormente, &.a es una exigencia basica que ya se da por asumida, pasando a primer plano aspectos como la seguridad e integridad de 10s datos, la posibilidad de acceder a ellos de manera simultanea desde multiples puntos, el rendimiento en la ejecuci6n de las operaciones, etc. La expansion de las tecnologias WWW en las aplicaciones actuales, tanto internas como de cara a1 publico, t a m b i h ha aportado nuevas necesidades, como el acceso a 10s datos a trav6s de redes publicas, principalmente Internet, o la transformation a y desde estandares como XML. Las necesidades de las aplicaciones se convierten, tambi6n de manera invariable, en trabajo adicional para el desarrollador. A1 fin y a1 cabo, todas esas capacidades han de implementarse de alguna forma. Es precis0 conectar con el origen de 10s datos, transferirlos hasta la aplicacion, procesarlos internamente o bien con intervenci6n del usuario y, finalmente, devolverlos a su origen debidamente actualizados. Para efectuar ese trabajo es necesacio disponer de soluciones.

Las soluciones o mecanismos de acceso a datos han sido y, por ahora, seguirfin siendo muchos y diversos. Tenemos lenguajes que gestionan directamente sus formatos de archivo, C O ~ Oes el caso de 10s conocidos como archivos indexados de COBOL; motores de acceso a datos que pueden usarse desde distintos lenguajes, como DAO, ADO o BDE; bases de datos que cuentan con su propio lenguaje de programaci6n, desde dBase y Access hasta cualquier RDBMS actual, y plataformas que cuentan con sus propios servicios de datos, como JDBC y ADO.NET. Normalmente cada una de esas soluciones est6 asociada a una determinada herramienta de desarrollo o lenguaje, o bien a un modelo de objetos, sistema o plataforma. DAO y ADO, por poner un ejemplo, s610 existen en Windows y, adem&, s610 pueden ser usados desde lenguajes que contemplan el trabajo con objetos COM, mientras que JDBC es Litil s610 en caso de que se trabaje con el lenguaje de programaci6n Java. Cada una de estas soluciones tiene sus particularidades, problemas, ventajas y requerimientos. La elecci6n de una de ellas suele limitar 10s origenes de datos a 10s que puede accederse, determinar el rendimiento y la escalabilidad de las aplicaciones. No es el objetivo de este libro entrar en 10s detalles especificos de cada una de ellas sino, como puede imaginar, centrarnos en el estudio de ADO.NET.

La plataforma Microsoft .NET supone un nuevo universo de posibilidades para 10s programadores. Pueden elegir el lenguaje de programaci6n que requieran sin, por ello, comprometer 10s servicios a 10s que tienen acceso o las posibilidades de compartir c6digo con otros desarrolladores. La CLS representa una interoperabilidad entre lenguajes sin precedentes hasta ese momento. El c6digo MSIL es independiente de procesador y sistema operativo, lo cual permite ejecutarlo en plataformas como Pocket PC, Linux o FreeBSD. En la plataforma Microsoft .NET existe una biblioteca de clases que representan 10s servicios de la propia plataforma, entre 10s cuales se encuentra ADO.NET: la soluci6n de acceso a datos de Microsoft .NET. Estos servicios pueden emplearse desde cualquier lenguaje .NET sin diferencias, si bien en este libro se ha optado por basar 10s ejemplos en Visual Basic .NET a1 considerarse el lenguaje m6s extendido en este momento. El cbdigo, no obstante, puede aplicarse a C# y otros lenguajes .NET previa conversion de sintaxis, manteniendo exactamente las mismas clases de objetos, metodos, propiedades y eventos. ADO.NET es una solucidn global de acceso a datos diseiiada como una evoluci6n de ADO. Decimos global porque puede aplicarse tanto a casos simples, aplicaciones en las que 10s datos se alojan en un archivo en el propio ordenador; hasta las tipicas aplicaciones cliente / servidor, con conexi6n permanente o no a1 origen

Prograrnacidn de bases d e datos con Visual Basic .NET

de datos; aplicaciones en varias capas o n-tier y, por supuesto, aplicaciones distribuidas basadas en Internet. Con ADO.NET es posible acceder a practicamente cualquier origen de datos, ya sea local o remoto, estructurado o jerArquico, basado en DBMS o no. El rendimiento obtenido es, en la mayoria de 10s casos, superior a la de otras soluciones existentes en la actualidad. En ADO.NET se ha optado por un nuevo esquema de trabajo con 10s datos, un esquema en el que se prescinde de elementos como la conexi6n continua con el servidor u origen de datos, la ejecuci6n de un cursor de acceso a la informacion o la representaci6n binaria de forma interna. El resultado es un increment0 en rendimiento, escalabilidad, compatibilidad y transportabilidad, asi como un menor us0 de recursos en 10s servidores. Como tendr6 ocasi6n de ver en este libro, podemos usar ADO.NET para trabajar con documentos XML, bases de datos Microsoft Access, SQL Server, Oracle y, en general, cualquier origen para el que exista un controlador OLE DB u ODBC lo que, en la prgctica, significa pricticamente todos 10s origenes posibles.

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, facilitar de forma notable nuestro trabajo. Dicho entorno cuenta con elementos que, como el Explorador de servidores, nos permiten establecer conexiones con origenes de datos, seleccionar conjuntos de informacibn, definirlos, crear autom6ticamente 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 aprovechar 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 conocer 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 previa. 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 construir aplicaciones Windows y Web. Para alcanzar estos objetivos es indispensable que su configuraci6n, la del equiPO donde va a probar 10s ejemplos propuestos, cuente con estos elementos: 0

Tener instalado Visual Basic .NET Standard o algunas de las ediciones de Visual Studio .NET. El autor ha empleado la edici6n Enterprise Architect de Visual 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, entre 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 didictico, por ello 10s fundamentos y conocimientos se van abordando de manera escalonada, capitulo a capitulo, asumiendo que 6sa sera la secuencia inicial de lectura. 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 capitulos, 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 relaciones y restricciones, trabajar con conjuntos de datos o usar XML con ,ADO.NET.

Programacidn de bases de datos con Visual Basic .NET

En la tercera parte se tratan las herramientas visuales de datos de Visual Studio .NET, mediante las cuales pueden facilitarse muchas de las tareas que, en la parte anterior, se han efectuado manualmente mediante la escritura de c6digo. Tambi6n se estudian 10s componentes con vinculaci6n a datos que simplifican la construcci6n de interfaces de usuario. Por dltimo, en la cuarta parte, encontrarQuna serie de capitulos en 10s que, de forma especifica y mediante un ejemplo, se aborda la resoluci6n de un cierto caso: la ejecuci6n de un procedimiento almacenado en SQL Server, la creaci6n de una columna calculada en un conjunto de datos o el almacenamiento y recuperaci6n de imQgenes,son algunos de 10s temas estudiados.

B, Internet

Figura 1.1. Sede Web de la editorial Anaya Multimedia

lntroduccidn

En caso de encontrar algun problema con este libro o el CD-ROM que le acompaiia, el lector puede recurrir tanto a la editorial como directamente a1 autor. Desde la Web de la editorial, en http: //www.AnayaMultimedia.com,puede 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, cualquier origen de datos. Como programadores, el autor asume que ya se conocen 10s terminos habituales en cualquier lenguaje de programach: variable, bucle, sentencia, expresi6n condicional, compilaci6n, etc. No se asume, por el contrario, ningiin 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 abordan 10s elementos que podrian considerarse bisicos: ique es un DBMS o el lenguaje 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, conceptos 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 plataforma .NET.

En el tercer capitulo se entrarii a estudiar con mayor detalle la naturaleza de 10s origenes de datos, describiendo basicamente aquellos m6s conocidos a 10s que podemos acceder desde Visual Basic .NET usando ADO.NET.

S 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 informaci6n 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 amigable. 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 fisicamente 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 estructura 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 informaci6n o DBMS, aplicaciones cuyo objetivo no es s610 almacenar y recuperar datos,

1. Terrninologia y conceptos

sin0 tambien facilitar la manipulaci6n de 6stos de la forma m6s eficiente y segura Un servidor de datos debe elaborar la informaci6n que va a devolver a1 cliente partir de 10s datos recuperados del sistema de archivos, usando para ellos diferen tes estructuras fisicas, asi como asegurar su integridad verificando restricciones utilizando transacciones, temas que se tratar6n de inmediato. Aunque en un principio surgieron DBMS de distintos tipos, segun la estructur con la que se almacenaba la informacibn, 10s m6s extendidos y conocidos son 10 RDBMS, llamados asi porque 10s datos se estructuran con ciertas relaciones entr ellos, simplificando la recuperaci6n y el tratamiento y evitando la repetici6n inne cesaria de informaci6n. Algunos ejemplos de RDBMS son 10s ya mencionados SQ Server, Oracle, DB2 o InterBase.

Tambien se conoce a 10s DBMS por sus siglas en nuestro idioma, SGBD, aunque su us0 es menos habitual.

Arq uitectu ra clienteiservidor

Durante aiios, las bases de datos se han utilizado en sistemas que se ajustaban una arquitectura conocida como clientelservidor. En ella 10s datos residen en u ordenador que actua como servidor, ejecutando el software que denomin6bamo antes servidor de datos. Los usuarios, desde ordenadores remotos, se sirven de u software cliente para comunicarse con el servidor de datos. Ese software cliente e especifico para cada servidor de datos existente. Supongamos que estd utilizando SQL Server como servidor de datos, estand instalado dicho software en una mAquina que reside en un centro de proceso d datos. Desde su ordenador, ubicado en otra planta del mismo edificio, se comun caria con ese servidor mediante el software cliente de SQL Server que, 16gicame te, deberia estar instalado en su m6quina. Dicho software cliente no serviria par comunicar con un servidor Oracle o DB2, por poner un caso, teniendo que dispo ner del software cliente que corresponda en cada caso.

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 arquitectura 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 encontrasen 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 / servidor. 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 instalados.

Cliente 1

Cliente 3

Cliente 2

Router

1

Servidor de datos

Figura 1.2. Configuracion clientelservidor de acceso a una base de datos

1 . Terrninologi'a y conceptos

Partiendo del modelo cliente / servidor, descrito brevemente en el punto anterior, han surgido otros conocidos gen6ricamente como n-tier, siendo el m i s habitual el three-tier o de tres capas. En dicho modelo 10s clientes no se comunican directamente con el servidor de datos, sino que entre ellos se interpone un nuevo servidor: e de aplicaciones. La figura 1.3 es una representaci6n visual de este modelo.

,

Cliente I

aplicaciones

Cliente 2

1

Cliente 3

Servidor de datos

Figura 1.3. Un sistema distribuido en tres capas

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

Dichos componentes, adem&, alojan la 16gica de proceso de la informacibn, lo que normalmente se conoce como reglas de negocio, tarea que en el modelo cliente / servidor recaia en la aplicaci6n del cliente. De esta forma, el cliente queda relegado a una simple interfaz de usuario, ya sea nativa en un ordenador, un documento en un navegador Web o desde un dispositivo m6vil. La ventaja principal es que resulta mas f6cil llegar a clientes heterogheos y dispersos, interconectados no en redes de la propia empresa sino a travks de Internet. En cuanto a nosotros respecta, la unica diferencia seria que la aplicaci6n estaria dividida en dos apartados: la interfaz del usuario, por una parte, y 10s componentes que se ejecutarian en el servidor de aplicaciones y accederian a 10s datos, por otra.

Aunque ciertos tipos de informacion son accesibles para el usuario mediante aplicaciones especializadas, por ejemplo Microsoft Excel para las hojas de calculo o Paradox para las bases de datos propias de Paradox, en la mayoria de 10s casos el usuario necesitar6 una soluci6n a medida de sus necesidades, en lugar de otra general. No seria logico, por ejemplo, que 10s usuarios utilizasen el software de administraci6n para operar directamente sobre un servidor de datos como SQL Server u Oracle. Aparte de complejo para aquellos que no tienen conocimientos de bases de datos y del lenguaje SQL, esa posibilidad pondria en peligro la propia seguridad de 10s datos. Gracias a esa necesidad de 10s usuarios tenemos trabajo 10s desarrolladores, creando aplicaciones segun las caracteristicas, conocimientos y necesidades de nuestros clientes. Para que nuestros programas puedan trabajar con 10s archivos donde reside la informacidn, no obstante, necesitaremos diversas herramientas, entre ellas uno o varios servicios de acceso a datos. Por ejemplo un componente para poder operar sobre las hojas Excel, otro para comunicarse con bases de datos, un tercero para leer y escribir documentos XML, etc. Aqui es donde entra en escena ADO.NET, nombre con el que se denomina gen6ricamente a 10s servicios de acceso a datos de la plataforma Microsoft .NET. ADO.NET, adem&, es una soluci6n global para el acceso a la informacibn, no necesitamos otros servicios segun el tip0 de datos con 10s que vayamos a trabajar. Como se indicaba anteriormente, con ADO.NET podemos tanto operar sobre archivos XML, documentos Excel, bases de datos locales y remotas, etc.

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 controladores. 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 documento XML. Aplicacion cliente

0,

I

IBMDB2

Figura 1.4. Acceso a d o s origenes de datos diferentes

El lenguaje de consulta de datos por excelencia entre 10s RDBMS es SQL, creado hace algo m6s de veinte afios y conocido originalmente como SEQUEL. Realmente 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 almacenados. 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.

Ciriiendonos ya a las bases de datos relacionales, posteriormente en otros capitulos nos ocuparemos del resto de origenes de datos, encontramos una serie de terminos y conceptos que tambien es precis0 conocer. Los RDBMS introducen la informaci6n en tablas, que pueden ser consideradas como conjuntos de entidades cada una de las cuales tiene una serie de atributos. Los atributos almacenan datos en un cierto dominio y, en algunas ocasiones, sirven para establecer relaciones con otras entidades. Los puntos siguientes son un recorrido rdpido por 10s conceptos mds importantes relativos a la estructura de la informaci6n en un RDBMS, independiente de cud1 sea este.

~

-

~

~

.

-

-

_

_

_

La informaci6n almacenada en una base de datos pertenece generalmente a objetos reales que es posible identificar fdcilmente. Esos objetos cuentan con una serie de propiedades. Por ejemplo, un libro tiene un titulo, una editorial, un autor, un ISBN, un precio, un numero de piiginas, etc. Toda la informacih de ese objeto formaria una entidad, mientras que cada dato seria un atributo de la entidad. Los atributos de una entidad se reparten en una fila, ocupando cada atributo una colurnna. A1 conjunto de varias filas, cada una con identicos atributos per0 diferentes valores, es a lo que se conoce como conjunto d e entidades, con estructura de tabla bidimensional. En la figura 1.5 puede ver un conjunto de entidades formado por tres entidades, cada una de las cuales cuenta con cuatro atributos. Observe que todas las entidades que pertenecen a un conjunto tienen 10s mismos atributos, aunque sus valores Sean diferentes. Es decir, todos 10s libros tienen un titulo, una editorial, un ISBN y un numero de pdginas, aunque el titulo de cada uno sea distinto a1 igual que el ISBN o el numero de pdginas. En un RDBMS ese conjunto de atributos seria una tabla, cada entidad seria una fila y cada atributo una colurnna. A1 trabajar con bases de datos de escritorio es habitual llamar carnpo a cada atributo y registvo a cada entidad.

Atributo Titulo

Atributo Editorial

Atributo ISBN

Atributo

Pdginas

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 dominio. 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 integridad de la informaci6n. A1 tiempo, se evita que la aplicaci6n tenga que estar comprobando 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 informaci6n 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 restricci6n que le obliga a contener un valor unico entre el conjunto de entidades, utilizindose 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 claves 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

En el ejemplo mostrado en la figura 1.5, el atributo I S B N podria actuar como identidad de cada entidad ya que es irrepetible. En el caso de que las entidades no dispongan de un atributo de este tip0 se afiadiria un atributo artificial que permitiese la identificacihn.

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 posterior, 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. vlsuai B ~ S ~. NCE T V i s u a l CB .NET Visual S t u d i o .NET

1 1 1

e4-115-1351-1 84-415-1392-9 84-415-1376-7

672 656 65h

Figura 1.6. Relacion entre dos conjuntos de entidades

El atributo Editorial de la primera entidad que hay en el primer conjunto indica que la editorial es la numero 1, estableciendo asi una relaci6n con la primera entidad del segundo conjunto. El numero 1 es el atributo identidad o clave primaria de cada entidad editorial, mientras que actua como clave externa en la entidad correspondiente a cada libro. Estas claves tambi6n suelen conocerse como PK y FK. Mediante una restricci6n de integridad referencial se evitaria que el usuario pudiese introducir en una entidad de la tabla de libros un c6digo de editorial que no existiese en la segunda tabla. De manera anAloga, otra restricci6n podria impedir la eliminaci6n de una editorial del segundo conjunto mientras existiesen en el primer0 entidades que hicieran referencia a ella. Las relaciones entre tablas pueden ser de diversos tipos, siendo las mAs habituales las conocidas como uno-a-uno y uno-a-muchos. En el primer caso a cada entidad del primer conjunto le corresponde s610 una entidad del segundo. Es lo que ocurre en el caso de la figura 1.6, en el que cada fila de la tabla de libros apunta a una sola fila de la tabla de editoriales. Si invirti6semos la relaci6n (v6ase figura 1.7), por el

Programacidn de bases de datos con Visual Basic .NET

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

V i s u a l 5ds1c .NET V i s u a l C # .NET V i s u a l S t u d i o .NET

1 1

1

84-415-1351-1 84-415-1392-9 84-415-1376-7

672

656

656

Figura 1.7. Relacion de tip0 uno-a-muchos

Al hablar de relaciones suele usarse con cierta frecuencia el termino maestrodetalle. Hace referencia a un tip0 de relacion en la que una tabla actua como maestra o primaria y otra como tabla de detalle o secundaria, dando lugar a una relacion uno-a-muchos.

A1 trabajar con tablas de tamafio considerable, con muchos miles 0, incluso, millones de filas, el proceso de recuperaci6n de datos puede verse afectado de manera 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 puede 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 tambi6n 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

En capitulos posteriores podri conocer 10s fundamentos de la definici6n de procedimientos almacenados en algun RDBMS, asi como su ejecuci6n desde una aplicaci6n propia a travks de ADO.NET.

---- -

--- --

I_

I_

___I

I

-

-~

-___-

- -

_I

El proceso de normalizacion de una base de datos se compone de varios pasos que se apoyan en un conjunto de reglas formales relativamente estrictas. De lo que se trata, bisicamente, es de racionalizar tanto el contenido de las tablas como las relaciones existentes entre ellas, persiguiendo la menor repeticion de informaci6n y la mayor flexibilidad. En una base de datos normalizada lo habitual es que exista un mayor numero de tablas que en otra que no lo esta. En consecuencia, las tablas normalizadas suelen ser mas pequefias, con menos atributos, que las tablas no normalizadas. Dos de Ias reglas fundamentaIes de este proceso son: Cada entidad debe contar siempre con un atributo identidad que actue como clave primaria y unica, facilitando de esa manera la identificacih inequivoca 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 normalizaci6n Sean kstos, existen otros que tambikn deberian considerarse para conseguir 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 deben 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 impliquen 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 bancarias. Atendiendo a un cliente que quiere efectuar una transferencia desde su cuenta 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 produce 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. Simplemente 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 cambios se confirman. Para que este sistema sea realmente util es necesario que el sistema de transacciones del RDBMS cumpla con las propiedades conocidas como ACID: 0

0

La atornicidnd de la transacci6n hace que todas las operaciones que comprende 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. Mediante la consistencia se garantiza el cumplimiento de las reglas que lleven asociadas las operaciones introducidas en la transaccibn, tales como restricciones, 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 transaccion no Sean visibles en otras hasta que se confirme. Asi se consigue una independencia total en el trabajo de multiples transacciones concurrentes.

0

Por ciltimo tenemos la durabilidad o persistencia, la propiedad que da la garantia 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 conocido como limbo, de la cual se recuperaria posteriormente. Las transacciones se confirman o se rechazan. La confirmacidn de una transacci6n 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 segun 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 formato binario, como venia siendo habitual en cualquier medio para el almacenamiento de datos, sin0 como texto simple, facilitando asi la comunicaci6n entre aplicaciones 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 obtener 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 documentos XML. Como veremos posteriormente, tambien podemos actuar sobre ellos mediante ADO.NET, como si fuesen origenes de datos locales.

A1 finalizar el primer0 de este trio de capitulos introductorios ya conoce una parte del vocabulario que usaremos en el resto del libro, asi como conceptos fundamentales que puede ampliar recurriendo a otras fuentes especificas. En la mayoria de ejemplos que se propondrdn posteriormente trabajaremos sobre una arquitectura cliente/servidor o de tres capas, aunque tambien se abordar6 el us0 de origenes de datos locales como documentos XML. Tambi6n en 10s capitulos siguientes tendr5 oportunidad de conocer SQL y aprender a definir bases de datos y sus distintos elementos en ciertos sistemas RDBMS.

x_l. ....I.,

.,...

.... '. ....

'

,.-.

.... :7?.

A pesar de que nuestro papel en la empresa este m6s cerca, o sea puramente, del desarrollador que del administrador de bases de datos, lo cierto es que conocer el lenguaje SQL resultar6 totalmente imprescindible. ADO.NET, como veri en su momento, cuenta con componentes capaces de generar las sentencias SQL necesarias para actuar sobre las bases de datos, per0 ser6n muchos 10s casos en que dichas sentencias deban facilitarse desde la aplicacion que estemos creando. Actualmente todos 10s DBMS, incluidos aquellos que no son servidores como es el caso de Access o dBase, contemplan el us0 del lenguaje SQL para efectuar cualquier tarea sobre la informacion, desde la definition de su estructura hasta la manipulaci6n de 10s datos propiamente dichos. Algunos RDBMS, realmente todos aquellos que contemplan la definici6n de procedirnientos alrnacenados, utilizan tambien SQL como base para un lenguaje propi0 de tip0 procedimental. El objetivo de este capitulo es acercarle a1 lenguaje SQL, facilitando una explicaci6n de sus estructuras b6sicas que le permitan, por ejemplo, crear una tabla, seleccionar un conjunto de datos o modificar informaci6n ya existente en la base de datos. Tambien se facilita, a1 final del capitulo, una breve introduccih a dos derivados de SQL: Transact-SQL y PL/SQL. Obviamente no se intenta abordar la sintaxis completa de SQL y todas sus posibilidades. Si necesita conocer a fondo este lenguaje siempre tiene la posibilidad de recurrir a un texto especifico o la referencia del lenguaje de su RDBMS en particular.

2. S Q L y sus dialectos

Como su propio nombre indica, SQL es un lenguaje para consulta de datos. A diferencia de 10s lenguajes de programacibn que estard acostumbrado a usar, en SQL no existen ciertos elementos, como las estructuras de control, por lo que no es un lenguaje que pueda ser utilizado para crear procedimientos. Su finalidad b6sica es facilitar la manipulaci6n de datos como si fuesen conjuntos, en contraposici6n a1 tratamiento que se e f e c t ~ adesde 10s lenguajes de programacidn, donde cada dato se procesa de manera individual. SQL es un est6ndar ANSI, lo cual significa que existe una especificaci6n creada por dicha institucih y que, en principio, deberiamos poder w a r exactamente la misma sintaxis independientemente del RDBMS concreto que vayamos a utilizar. La realidad, sin embargo, es que cada RDBMS incorpora sus mejoras o extensiones particulares a1 SQL esthdar, dando asi lugar a implementaciones especificas e incompatibles con las del resto de fabricantes. Existe, no obstante, un conjunto de SQL que podriamos calificar de rninirno comtin denominador, a1 ser idbntico, o casi, en todos 10s RDBMS existentes.

El lenguaje SQL est6, en realidad, compuesto de varios sub-lenguajes, entre 10s cuales destacariamos 10s tres siguientes: 0

0

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, actualizaci6n 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. DDL: Con las sentencias DDL no se manipulan 10s datos propiamente dichos, sino la informacih de su estructura. Con las sentencias DDL pueden definirse las columnas de una tabla y sus atributos, eliminar o crear un indice, etc.

DCL: Mucho menos conocido que 10s dos anteriores, este lenguaje se compone de sentencias especificas para garantizar la seguridad de acceso a 10s datos, facilitando la gestion de usuarios y el otorgamiento o denegaci6n de 10s permisos necesarios para operar sobre cada elemento de la base de datos.

Tedricamente, la definici6n de las estructuras de la base de datos, asi como 10s temas relativos a la seguridad, deberian quedar en manos del administrador del RDBMS de la empresa a la que se dirija la aplicacidn, de tal manera que el desarrollador s610 precisaria conocer el subconjunto DML de SQL para poder ejecutar consultas y manipular 10s datos segun las necesidades de 10s usuarios de las apli-

r Programacidn de bases de datos con Visual Basic .NET

caciones. En 10s puntos siguientes, no obstante, tambien encontrari una r6pida introducci6n a algunas de las sentencias de DDL y DCL.

Si bien, en un principio, la finalidad de 10s RDBMS era bisicamente la de almacenar, recuperar y manipular la informacidn, segun las sentencias SQL facilitadas desde algun tip0 de aplicaci6n o por el usuario, con el paso del tiempo se han ido confiando a estos sistemas de tratamiento de datos otras tareas adicionales. Una de ellas es la ejecuci6n de una cierta 16gica de proceso que asegure la integridad de 10s datos 0,simplemente, haga m i s f6cil su tratamiento por parte de las aplicaciones. Estas operaciones se implementan en forma de desencadenadores y procedimientos almacenados, siendo precis0 un lenguaje de programaci6n para efectuar dicha implementacibn. SQL, como se ha dicho antes, no es un lenguaje procedimental y, por tanto, no puede ser utilizado para dar soluci6n a estas necesidades. Por esa raz6n, cada fabricante de RDBMS incorpora en su product0 un lenguaje propio para desempefiar esas tareas. Por regla general, estos lenguajes tienen una sintaxis basada en la de SQL, aportando 10s elementos necesarios para definir procedimientos, evaluar expresiones condicionales o definir una ejecucidn reiterada. Dos de 10s lenguajes derivados de SQL m i s conocidos son PL/SQL, propio de las bases de datos Oracle, y T-SQL (tambien conocido como Transact-SQL), que podemos encontrar en SQL Server o Sybase. Lbgicamente, necesitaremos aprender uno u otro dependiendo del RDBMS que utilice nuestra empresa.

Las bases de escritorio, como dBase, Access y Paradox, no disponen de un lenguaje similar a PL/SQL o T-SQL para la implernentacion de procedimientos almacenados, pues dichos elementos no existen en esos productos. Si cuentan, sin embargo, con un completo lenguaje de programacion que permite crear verdaderas aplicaciones, en contraposicion a la Iogica discreta, siempre dirigida al tratamiento de datos, para la que estan pensados PL/SQL y T-SQL.

A partir del punto siguiente va a ir conociendo multiples sentencias SQL para selecci6n de datos, modificacibn, eliminaci6n y definici6n de algunas estructuras. Estas sentencias no puede introducirlas, sin mis, en el editor de Visual Basic .NET y esperar a que funcionen, puesto que su entorno de trabajo es el interior de un RDBMS. Si quiere ir comprobando 10s ejemplos propuestos, lo que no es totalmente necesario para comprender la sintaxis de SQL, deberi recurrir a la herramienta especifica de la base de datos que pretenda emplear en sus desarrollos.

2.S Q L y

sus dialectos

Puede usar una base de datos de escritorio, por ejemplo Microsoft Access (v6ase 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

Debe tener en cuenta que la compatibilidad de las distintas implementaciones SQL en cada RDBMS respecto al estandar SQL, normalmente se toma como referencia SQL-92 y SQL3, es muy variable. Esto implica que algunas sentencias SQL puedan necesitar ligeros cambios segun la base de datos sobre la que vaya a ejecutarse.

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

albergarh. Estas estructuras conforman lo que se conoce habitualmente como el catulogo del RDBMS. Por esta raz6n comenzaremos introducihdonos en DDL, el lenguaje de definicih de datos.

Conexmes 1

Figura 2.2. El Analizador de consultas de SQL Server facilita la ejecuclon de se tencia SQL sobre este RDBMS, mostrando 10s resultados en la parte inferior de la ventana

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

Figura 2.4. La utilidad SQL*Plus de Oracle es posiblemente la mas rudimentaria, al estar practicamente basada en texto sin elementos de interfaz que faciliten las operaciones basicas

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 eliminar todos esos elementos. Los comandos DDL son tres:

CREATE: Se utiliza para crear bases de datos, tablas, indices, desencadenadores, 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 eliminarse, 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.

S La creaci6n de una nueva base de datos es un proceso relativamente complejo, a1 ser precis0 definir su contenido y estructura, espacio de almacenamiento, permisos de acceso, usuarios con que cuenta y otra serie de reglas adicionales. Por ello pr6cticamente todos 10s RDBMS incorporan un asistente para efectuar este trabajo, asistente que va dirigido a1 DBA. Como desarrolladores, tan s610 necesitariamos emplear la sintaxis siguiente en caso de que fuese imprescindible crear la base de datos desde nuestra propia aplicacih. La sintaxis bdsica para crear una nueva base de datos seria &a: 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 existir6n opciones adicionales para indicar la localizacih y nombre fisico de 10s archivos donde ser6 alojada, o bien ser una especificacion de nombre de archivo en si mismo, segun el RDBMS con que trabajemos.

Dependiendo del RDBMS empleado, tambien es posible utilizar 10s comandos DROP ALTER con DATABASE para eliminar una base de datos o modificar alguno de sus parametros.

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 atributos 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 primarias. 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

CREATE TABLE nornbre-tabla ( rmnlbre c o l u m n a t i p o o p c i o r l e s , nonibre c o l u m n a tip0 o p c i o n e s , ~

~

... I

Pueden existir pariimetros adicionales, per0 lo mas importante es el nombre que deseamos dar a la tabla y la lista con la definicih de las columnas, cada una de las cuales tendrii un nombre, un tip0 que determinara la clase de informacion que puede contener y opciones adicionales. Los tipos de datos suelen ser especificos de cada DBMS, si bien existe un conjunto basico definido en el estandar ANSI que mas o menos es compatible en todos 10s sistemas. Algunos de esos tipos son: INTEGER: Un numero entero, normalmente de 32 bits. 0

SMALLINT:Un numero entero de menor tamafio que el anterior, normalmente de 16 bits. CHAR (N): Una cadena de N caracteres con longitud fija.

0

VARCHAR (N) : Una cadena de hasta N caracteres, con longitud variable.

0

DATE:Una fecha.

0

TIME: Una hora. FLOAT:Un numero en punto flotante.

En SQL Server no existe el tip0 DATE y, en su lugar, se utiliza el tip0 DATETIME para alojar fecha y hora. En Oracle, a pesar de que existe el tipo estilndar VARCHAR, kste se encuentra en desuso y, en su lugar, se utiliza normalmente VARCHARZ. En realidad VARCHAR es, en Oracle 8i, un sin6nimo para VARCHAR2. Lo mismo ocurre con el tip0 INTEGER, que en Oracle es un sin6nimo de NUMBER ( 3 8 ) , a1 ser en dicho RDBMS el tip0 NUMBER el mas empleado para tipos numkricos. Tras el tip0 de cada columna, y de manera opcional, pueden aplicarse restricciones y definir claves. Algunas de las opciones posibles son:

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 perfectamente 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 incluidos en esta columna seran tinicos.

PRIMARY KEY: Establece la columna a la que acompafia como clave primaria 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 columna como disponerse a1 final de la lista de columnas, caso en el cual se indicaria entre 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 apartado REFERENCES ( col), donde col seria la referencia a la tabla y columna externa. A continuacibn tiene un ejemplo de creaci6n de una tabla simple: CREATE TABLE Libros ( IDLibro INTEGER PRIMARY KEY, ISBN CHHR(13I UNIQUE, Titulo VARCHAR(30) NOT NULL, Autor VARCHAR(501, FOREIGN KEY (Editorial1 REFERENCES Editoriales ( IDEditorial) )

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 valores 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 redundante aiiadir una columna como identidad de cada fila, en realidad estd ahorrdndose 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 Editorial 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 eliminarlo. Por ejemplo: ALTER TABLE Libros DROP COLUMN ISBN ALTER TABLE ADD ISBN VARCHAR(13) ALTER TABLE Libros ALTER COLIJMN Titulo VARCHAR(35)

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: DROP TABLE Libros

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, entre ellos 10s indices y las vistas. Para crear un indice utilizaria la siguiente sintaxis: CREATE INDEX NombreIndice ON NombreTabla(Co1umna)

Programacio'n de bases de datos con V i s u a l Basic .NET

El nombre de la tabla y la columna determinan la informaci6n a partir de la cual el DBMS generar6 el nuevo indice, a1 que llamar6 NombreIndice. El indice es en si una estructura ordenada que acelera tareas como las busquedas o la obtenci6n de 10s datos con un cierto orden. La creaci6n de un indice tiene sentido sobre aquellas columnas que van a emplearse con cierta frecuencia en las consultas para buscar u ordenar. Tras el nombre de la tabla y columna, de manera opcional, es posible indicar si el orden del indice ser6 ascendente o descendente, con las cl5usulas ASC y DESC, respectivamente. S610 puede aparecer una de ellas. La tabla Libros que hemos utilizado en 10s ejemplos anteriores dispone de una columna que actua como clave principal, per0 es de esperar que en la mayoria de las ocasiones la busqueda se efecttie a partir del ISBN. Con la siguiente sentencia SQL generariamos un indice que aceleraria dichas btisquedas. C R E A T E I N D E X I n d I S B N ON Libros ( I S B N )

Un indice puede eliminarse con la sentencia DROP INDEX NombreIndice y, en algunos DBMS, tambien modificarse mediante el comando ALTER. I

I

En cuanto a las vistas, podriamos definirlas como consultas SQL predefinidas, a las que se asocia un nombre, cuyo objetivo es facilitar la vida a 10s usuarios y programadores, por ejemplo evitando que tengan que componer complejas consultas con relaciones entre multiples tablas para obtener 10s datos que precisan. Las vistas se definen una vez, normalmente es trabajo del administrador o DBA, y posteriormente pueden ser usadas tantas veces como se necesite, apareciendo a 10s ojos de 10s usuarios como si fuesen tablas. La sintaxis para definir una nueva vista es &a: C R E A T E V I E W NombreVista AS Consulta

Para componer la consulta necesitaremos, ldgicamente, conocer la sentencia DML SELECT,que trataremos en un punto posterior. Aunque con ciertas limitaciones, es posible definir como vista pr6cticamente cualquier consulta. En el ejemplo siguiente se crea una vista que facilita todas las editoriales con 10s libros que tienen publicados, partiendo de las hipotgticas tablas Editoriales y Libros que se han empleado en ejemplos anteriores. 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 libros, 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 comandos CREATE, ALTER y DROP pueden utilizarse tambien para crear desencadenadores, 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 hacerse 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, consecuentemente, cuatro 10s comandos DML que necesitaremos para poder llevarlas a cabo: 0

0

0

SELECT: La sentencia DML por excelencia. Se utiliza para ejecutar consultas de recuperacih de datos. I N S E R T : Su finalidad es insertar nuevas filas en una tabla. 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

A diferencia de lo que ocurre con las sentencias de un lenguaje de programaci6n tipico, como puede ser Visual Basic, estas sentencias DML no actuan sobre un solo elemento, sin0 sobre conjuntos de filas y columnas. Es importante tenerlo en cuenta a la hora, por ejemplo, de utilizar una sentencia DELETE para eliminar una fila, puesto que, inadvertidamente, podemos afectar a varias 0, incluso, la tabla completa. En 10s puntos siguientes va a conocer la sintaxis b6sica de cada una de las cuatro sentencias indicadas, asi como a ver algunos ejemplos de su uso.

__

__

___

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 principio 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 INTO NornbreTabla

VALlJES

( v a l o r , valor

...)

Tras la palabra VALUES, y entre parhtesis, se facilitarin tantos valores como columnas existan en la tabla indicada y, ademhs, en el mismo orden y del mismo tipo. Los valores numericos se introducen tal cual, mientras que las secuencias de caracteres normalmente se delimitan entre comillas simples. Suponiendo que quisiksemos afiadir una fila a la tabla L i b r o s creada como ejemplo en un paso anterior, y que contaba con cinco columnas, utilizariamos una sentencia asi: 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: I N T O Libros ( I D L i b r c , , ( 1 , '84-415-1351-1')

INSERT

ISBN) V A L l J E S

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

Como se apuntaba anteriormente, la sentencia S E L E C T es la m i s conocida de SQL y es que, no en vano, es generalmente la m6s utilizada. Posiblemente tambien sea la que con m6s opciones y variantes cuenta, asi como algunas diferencias de implementaci6n segun el RDBMS. Lo habitual es que el resultado de una sentencia SELECT sea un conjunto de datos, compuesto de multiples filas y columnas, aunque tambien es posible recuperar un dato concreto como resultado de la evaluaci6n de una expresi6n. La sintaxis m6s sencilla de esta sentencia es la siguiente: SELECT C o l u m n a l ,

Colurnrla2,

...

FROM T a b l a

El conjunto de datos devuelto se compondri de las columnas seleccionadas en todas las filas de la tabla indicada tras FROM.Por ejemplo: 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 especificar 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

En este caso se obtendria la totalidad de la tabla L i b r o s , es decir, todas las filas con todas las columnas. Usualmente esto no es necesario, por ello se seleccionan s610 las columnas que se precisan en cada caso y, ademis, se limitan las filas mediante condiciones. Tambikn es posible establecer el orden en que se facilitan las filas recuperadas, agruparlas, efectuar consultas sobre consultas, etc. 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 necesario 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 dicho 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 : SELECT L.ISBN, L . T i t u l o , FROM L i b r o s L

L.Editoria1

Prograrnacidn de bases de datos con Visual Basic .NET

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 columna. 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 resultados 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 tkcnica similar, primer0 porque las filas no tienen nombres, sin0 que contienen valores, 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 pero, 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 devolver. 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

La condici6n se asemejard bastante a 10s condicionales que estamos acostumbrados a utilizar en Visual Basic, con operadores relacionales como =, < y > y operadores 16gicos como AND, OR y NOT. Esto permite una gran flexibilidad a la hora de seleccionar conjuntos de datos. Por ejemplo: SELECT I S B N , Titulo FROM Libros WHERE Autor='Bill Gates'

... SELECT I S B N , Titulo FROM LIBROS WHERE Editorial=S AND Precio FROM

dbo EditonalesINNER IOIN dbo Lbror ON dbo Editoriales IDEditorml = dbo Libros Editorid

*

1, Figura 3.20. Aiiadimos las tablas a la vista

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 columna Orden asociada a la P r e c i o para que 10s datos se ordenen ascendentemente 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 probar la vista y obtener, en la parte inferior, el resultado, como se ve en la figura 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

WHERE

dbo Libros ON dbo Edtormles IDEdibrial = dbo Libros Editwial 10 75AND 401

(dbo Libros Pieao EFliVEEN

Anaya Mulbmedia Inboducaon a la wogramaoon User Interface Desqn for Programmers Anaya Mulbmedia Programaaon con Ddph 6 y Kylix Anaya Mdbmedia Programauon con Visual Basic NET Anaya Mdbmeda Programaaon con Visual C 7 NET Anaya Mulbmeda Programaaon con Visual Studio NET McGrawHiM Manud del miucvocesadw 80386

Figura 3.21. Cornprobarnos el resultado de ejecutar la vista

6. Salga de la ventana de composicidn y despues guarde la vista con el nombre L i b r o s E d i t o r i a l . Si hace doble clic sobre ella, en el panel derecho del Administrador corporativo, veri aparecer una ventana de propiedades con el c6digo Transact-SQL utilizado para crear la vista.

Puede ejecutar la vista en cualquier momento, desde el propio Administrador corporativo de SQL Server, haciendo clic sobre ella con el b o t h secundario del rat6n y seleccionando la opci6n Abrir vista>Devolver todas las filas.

n

S

Hasta ahora, todos 10s elementos creados en la base de datos SQL Server han sido 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 remedio que escribir el cbdigo, ya que un procedimiento almacenado es, en si, un bloque de c6digo con un nombre.

3 . Origenes de datos

Seleccione la carpeta Procedimientos almacenados de la base de datos, abra el menu emergente y elija la opci6n Nuevo procedimiento almacenado. Se encontrard con un cuadro de didlogo en el que aparece la cabecera para el nuevo procedimiento. Debemos facilitar el nombre y, por supuesto, introducir la 16gica a ejecutar que, en este caso, serd la que puede ver en la figura 3.22. Se trata del procedimiento almacenado propuesto como ejemplo en el capitulo previo, cuyo objetivo es devolver como resultado el numero de titulos de la editorial cuyo c6digo se entrega como pardmetro 0, por defecto, el numero total de titulos de todas las editoriales.

T ~ O REATE PROCEDURE NurnTtdulos OEdtonal INTEGER

'-1

IL_

WHERE EdRonal OEdRonal

It

I

................ ............ i............... -alairt& "

"

- -1.11/11

.........

"

.i

Figura 3.22. lntroducimos el codigo del procedimiento almacenado

Tras escribir el d d i g o , pulse el b o t h Comprobar la sintaxis para asegurarse de que no ha introducido ningun error. A continuacih puede hacer clic en Aceptar para cerrar el cuadro de didlogo y crear efectivamente el procedimiento almacenado. En cualquier momento puede hacer doble clic sobre este para volver a abrir la ventana y editar el c6digo. Este procedimiento almacenado devuelve como resultado un valor Linico, en este caso un numero entero. Vamos a crear otro que retorne un conjunto de datos, por ejemplo el nombre de editorial y el numero de titulos de cada una de las editoriales que existan. Siga 10s pasos que se han indicado antes, eligiendo la opci6n Nuevo procedimiento almacenado, e introduzca el cddigo siguiente en la ventana: CREATE PROCEDURE NurnTitulosEditorial AS BEGIN SELECT E.Nombre, COUNT(L.Titulo) NurnTitulos FROM Editoriales E, Libros L WHERE E.IDEditoria1 = L.Editoria1

Programacion de bases de datos con Visual Basic .NET G R O U P BY E.Nombre

END

Lo que hacemos es ejecutar una consulta, devolviendo el resultado, en la que se agrupan las filas por editorial y se obtiene el numero de titulos. El identificador NumTi tulos que se ha puesto tras COUNT ( ) ser6 el nombre de esa columna, el numero de titulos, en el conjunto de resultados.

Aunque nuestro objetivo, a1 crear 10s procedimientos almacenados del punto anterior, es aprender a utilizarlos desde Visual Basic .NET, a fin de comprobar que el resultado que generan es el que esperamos, y no otro, deberiamos ejecutarlos en este mismo momento. Para hacerlo deberemos recurrir a1 Analizador de consultas SQL, seleccionando dicha opci6n del menu Herramientas del Administrador corporativo. Un procedimiento almacenado se ejecuta mediante la sentencia EXECUTE,tras la que debe entregarse el nombre del procedimiento almacenado y, en caso que sea necesario, 10s parametros apropiados. Por ejemplo, para ejecutar el procedimiento almacenado NumTitulosEditorial, el segundo que hemos creado, bastaria con introducir la sentencia EXECUTE NumTitulosEditorial y pulsar el bot6n Ejecutar consulta o la tecla F5. Es lo que se ha hecho en la figura 3.23, en la que puede ver, en la parte inferior, el conjunto de resultados obtenido.

2

Apress

3

HcGraw-Bill

1

Figura 3.23. El procedimiento almacenado NumTitulosEditorial devuelve un conjunto de resultados obtenido mediante una consulta

3 . Origenes d e datos

Si ejecuta el procedimiento almacenado NumTi tulos siguiendo el mismo mktodo, Vera que en la parte inferior aparece un mensaje indicando que se ha ejecutado con &xito,per0 no se muestra conjunto de resultados alguno. El Analizador de consultas SQL recoge 10s valores devueltos por consultas y 10s muestra, como se ha visto, en la parte inferior, per0 el procedimiento NumTitulos no devuelve conjunto de resultados alguno, tan s610 un numero entero. Para poder comprobar este procedimiento tendremos que recoger el valor devuelto en una variable, previamente declarada, usando a continuaci6n la sentencia PRINT para mostrar el contenido en el panel de mensajes, como se ha hecho en la figura 3.24. Si tras NumTitulos se pone el c6digo de una editorial, obtendra el numero de titulos con que cuenta esta. En caso contrario se indicara el numero total de titulos que hay en la tabla L i b r o s .

Figura 3.24. Para ejecutar el procedimiento NumTitulos y obtener el resultado tenemos que recurrir a una variable intermedia

SQL Server es un RDBMS de Microsoft en continua expansibn, especialmente desde la aparici6n de las versiones 7 y 2000, per0 actualmente el numero uno de 10s RDBMS sigue siendo Oracle. No es de extrafiar si se tiene en cuenta que es uno de 10s RDBMS m6s antiguos, y por tanto con mas experiencia, y que, adem&, esta disponible para multiples plataformas, desde sistemas personales con Windows o Linux hasta grandes sistemas, lo cual le otorga ventaja sobre un product0 que, como SQL Server, s610 puede ejecutarse en Windows.

Prograrnacidn de bases de datos con V i s u a l Basic .NET

Oracle siempre ha tenido fama de ser un producto robusto, fiable y muy escalable, per0 no precisamente ficil de instalar o administrar. Esto, por suerte, va cambiando 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 gratuito, 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.

Abra la carpeta Oracle - OraHome81 de la lista de programas, en el menu del b o t h Inicio, y seleccione la opci6n Database Administration>Database Configuration Assistant. Se pondri en marcha el Asistente de configuracion de bases de datos Oracle, mediante el cual, segLin se puede ver en la figura 3.25, podemos crear nuevas bases de datos, modificar la configuraci6n de las ya existentes y eliminar bases de datos. I

I

Cuando se instala Oracle se crea una base de datos de ejemplo, usualmente llamada o r a c l e , que podriamos utilizar, per0 vamos a crear otra para que conozca el proceso a seguir.

Bienvenido al Asistente de Confguracih de Bases de Datos Oracle Este asistente le lsermite crear. confgurar o borrar una base de datos Seleccione el procedimiento que desea realizar con este asistente.

e Crear una base de datos r Cambiar la confguraci6n de una base de datos

r

Borrar una base de d a b s

Figora 3.25. lnicio del Asistente de configuracion d e bases d e datos Oracle

3. Origenes de datos

Pulse el b o t h Siguiente dejando seleccionada la opci6n Crear una base de datos. En el paso siguiente podrfi elegir entre una base de datos Tipica y otra Personalizada. Deje marcada la primera opci6n y pulse de nuevo el b o t h Siguiente. Oracle puede crear una base de datos nueva copiando las estructuras bfisicas de un modelo ya existente, almacenado en el CD-ROM del producto, o bien creando dichas estructuras a partir de cero, lo cual siempre es m6s lento. Deje seleccionada la opci6n Copiar 10s ficheros de base de datos existentes del CD y pulse el b o t h Siguiente una vez m6s. En el siguiente cuadro de di5logo debe introducir el nombre global para la base de datos, asi como el SID o identificador 16gico. El primer0 se suele componer del nombre de la base de datos mAs un dominio, formando asi un identificador Gnico, mientras que el segundo es un identificador simple. Para este ejemplo, como se ve en la figura 3.26, llamaremos libros a la base de datos, como en 10s casos previos.

La base de datos OracleEi se identiftca inequivocamente mediante un Nombre de Base de Datos Global, normalmente con elformato "nombre dommio" lntroduzca el Nombre de Rase de Datos Global que desee asignar a esta base de datos

La base de datos esta referenciada por al menos una instancia de OracleEt identiflcada inequivocamente desde cualquier otra instancia de este ordenador mediante un identiftcador del sistema Oracle (SID) Se ha introducido un SID recomendado que puede aceptar 0 cambiar por otro valor

1II bro s

SID:

Figura 3.26. lntroducimos la inforrnacion de identificacion de la nueva base de datos

No tenemos mfis que pulsar el b o t h Terminar y responder afirmativamente a la pregunta de si desea iniciar la creaci6n de la base de datos. Act0 seguido aparecer6 una pequefia ventana (v6ase figura 3.27) en la que se indica el identificador de la base y 10s datos de las cuentas asociadas, tras lo cual se pone en marcha el proceso de creaci6n propiamente dicho (v6ase figura 3.28). Este puede tardar un cierto tiempo y finalizar6 con un mensaje de confirmacihn. 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 interior objetos tales como esquemas, tablas, procedimientos, etc.

Se va a clear una base de datos Oracle El nombre de la base de datos sera llbros El identlficador del sistema para la base de datos sera libros La clave para la cuenta INTERNALser6 -, para la cuenta SYS sera change-on-install y para la cuenta SYSTEM sera manager

Figura 3.27. lnformacion sobre la base de datos que va a crearse

Figura 3.28. Proceso de creacion de la base de datos

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 afiadirla. Seleccione la opcidn File>Add Database to Tree. Aparecer6 un cuadro de diglogo 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,haciendo clic a continuacidn sobre el b o t h OK. En ese momento la base de datos aparecer6 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 poner 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

To learn more ahout DB4 Studin, clirkthe Quick Tour bunon

Figura 3.29. lnterfaz de usuario del Oracle DBA Studio

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.

Se pone en marcha el asistente para creaci6n de tablas, compuesto de nada menos que trece pasos. En 10s puntos siguientes se detallan uno a uno, asumi6ndose que pulsari el b o t h Siguiente a medida que vaya ley6ndolos para ir de una ventana a la siguiente. 1. Introduzca el nombre de la tabla, en este caso EDITORIALES, y seleccione el esquema del que formari parte. Por defect0 aparece el esquema SYSTEM porque es la cuenta con la que hemos iniciado sesibn, per0 puede desplegar

Programacidn de bases de datos con V i s u a l Basic .NET

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 esquema SCOTT. 2. El segundo paso consiste en la definici6n de las columnas que tendri la tabla. 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

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. NOMBRE y DIRECCION: Selecci6n el tip0 VARCHAR2 introduciendo 50 en el apartado Size.

I

Columns Definftion Columns defined

Pmpetttesof col Column Name Column Datatype size

I1

Scale Does this column have a defaultvalue7If so, please enter

A

.xJ

Add

1 Remwe)

- Cancelar

J,

-

Awda

)

__ 4

@tarlor

Siguiente 9

Termlnar

1

Figura 3.30. Definicion de las columnas de la tabla EDITORIALES

3 . En la ventana siguiente podemos establecer una clave primaria para la tabla. Active la opci6n Yes, I want to create a primary key y haga clic en la columna Order de IDEDITORIAL, convirtihdola en la finica partkipante de la clave principal. 4. A continuaci6n encontrari las opciones necesarias para definir algunas restricciones, concretamente las de permitir o no valores nulos y duplicaci6n de valores. En la columna de la izquierda seleccione la columna IDEDITORIAL y, a continuaci6n, marque las opciones No, it cannot be Null y Yes, it must be

3 . Origenes de datos

Unique a la derecha. A continuacibn podria establecer restricciones similares para las otras columnas, aunque en este caso las dejaremos con sus valores por defecto.

5. El paso 5 de 13 permite definir claves externas, algo que en el caso de la tabla EDITORIALES no es aplicable. Por lo tanto, pulsamos directamente el bot6n Siguiente.

6. Otro paso que nos saltaremos serfi el sexto, ya que no vamos a aplicar restricciones adicionales de comprobaci6n a ninguna de las columnas de esta tabla. Como se aprecia en la figura 3.31, no tenemos m6s que elegir una columna, a la izquierda, e introducir la restricci6n a la derecha tras activar la opci6n Yes, the column has a Check Condition. En la parte inferior aparecen algunos ejemplos.

Figura 3.31. Restricciones de comprobacion para las columnas

7. La ventana de este paso se emplea para introducir opciones especificas sobre almacenamiento. Dejaremos la configuraci6n por defecto y pasaremos a la siguiente. Dado que hemos dejado en algunos apartados 10s valores por defecto, el asistente pasa directamente a1 paso 13 y nos muestra la sentencia SQL que se utilizarfi para crear la tabla (v4ase figura 3.32). Basta con pulsar el b o t h Terminar para proceder a la creaci6n de la tabla. Utilizando el mismo asistente, vamos ahora a crear la tabla LIBROS.h a contarfi con las mismas columnas que ya definimos previamente en SQL Server o Access, per0 con 10s tipos de datos de Oracle. La columna IDLIBRO, por ejemplo, ser5 de tipo NUMBER, a1 igual que EDITORIAL y PRECIO; ISBN Ser6 de tipo CHAR con una

Programacidn de bases de datos con Visual Basic .NET

longitud de 13 caracteres y las demhs columnas serhn de tipo VARCHAR y 50 caracteres como limite. Defina la columna IDLIBRO como clave primaria y apliquele las restricciones necesarias para evitar que se introduzcan valores duplicados o que quede con un valor nulo. Tambikn puede aplicar las mismas restricciones a la columna ISBN. En el paso cinco deberh establecer la relaci6n entre la columna EDITORIAL de esta tabla e IDEDITORIAL de la tabla EDITORIALES, tal y como se muestra en la figura 3.33. Asi se asegura la integridad referencial entre ambas.

Name UBROS Schema SCOl?

S "NOMBRE" VARCMRZ(50) NOT NUL1"DIRECCION"VARCWZ(50 NULL CONSTMINT" PRIMARY KEYCIDEDITORW). UNIQU TABLESPACE 'SYSTEM'

'I

Figura 3.32. Resumen de la creacion de la tabla

Foreign Constraint constraints on column EDITORW

-

Column Name EDiTORlM Column Dataiype NUMBER(3Z)

@

Yes,me column is 8

Figura 3.33. Definimos las restricciones de integridad referencial

Ahora puede pulsar directamente el boton Terminar para ir a1 ultimo paso del asistente, revisar la sentencia SQL y, pulsando otra vez el b o t h Terminar, crear la tabla. En este momento ya tenemos definidas las estructuras que necesitamos.

Summaw Name Schema

LIBROS SCOTT

SQL generated

ll__..l__ _ _ I -.__-l__ll_.l_____lll__ __.~ l

_

_

l

_

_

^

_

~

_

_

l

~

REATE TABLE "SCO~.~'LIBROS'('IDLIBRO"NUblBER(32) NOT NULL, "ISBN' CHAR(13) NOT NULL,"TITULO VARCHAR2(50) NOT NULL, "AUTOR" VARCHARZ(SO), "EDITORIAC' NUMBER(32) NOT NULL, "PRECIV NUMBER(5,2), CONSTRAINT"" PRlMP,RY EYC'IDLIBRO"). VNlQUE('IDLIBRr3"). UNIQUE( "ISBN), FOREIGN KEYrEDITORIAC') REFEREMCES "SCOlT."EDITORIALESCIDEDITORIAC')) TABLESPACE "SYSTEM

I

t'

Figura 3.34. Resurnen de la creacion de la tabla LIBROS

El mecanismo de edici6n de datos de Oracle se asemeja, en funcionamiento, a1 visto anteriormente para SQL Server, si bien resulta algo m6s rudimentario ya que 10s cambios no van confirmandose a medida que se pasa de una fila a otra, sin0 que van generando una o m6s sentencias SQL que no se ejecutan hasta que lo confirmamos explicitamente. Seleccione la tabla EDITORIALES en el panel derecho del Oracle DBA Studio, haga clic sobre ella con el b o t h secundario del rat6n y elija la opci6n Table Data Editor. Inicialmente aparece una rejilla vacia. Puede ir introduciendo 10s datos de las editoriales, incluido el identificador puesto que no hemos preparado ningun mecanismo que lo genere autom6ticamente. Utilizando 10s botones que tiene a la izquierda puede acceder a1 c6digo SQL que se va generando a medida que introduce datos, como en la figura 3.35. Dichas sentencias se ejecutaran en el momento en que pulse el b o t h Apply. A continuaci6n haga lo mismo con la tabla L I B R O S , teniendo en cuenta que debe facilitar un identificador unico para cada fila y, ademas, introducir el c6digo de cada editorial definida en la tabla anterior. Cualquier error de restricci6n provocarA un mensaje de error similar a1 de la figura 3.36, en el que se comunica que se ha dado un c6digo de editorial inexistente.

Programacion de bases de datos con Visual Basic .NET

I I:

#

lDEDllORlAL

NORIBRE

ci ~-

_ _ .DlRECClON .. - .-.

i__._ __I_-

Anaya Multimedia

Juan lgnacio Luca de Tena, 1 5

McGraw-Hill

EdiRcio Valrealty, l'planta

Figura 3.35. lntroducimos una serie de filas en la tabla EDITORIALES

4

ORA*02291 resmccion de lntegrldad (SCOTT SYS-CO01276)nolada- claw padre no encontrada

Figura 3.36. Error provocado al violarse una de las restricciones

_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 titu10s que le corresponden. Seleccione la carpeta View, en el panel izquierdo del Oracle 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

el nombre de la editorial, el titulo y el precio de cada libro. Pulse entonces el b o t h Siguiente.

Selected Columns

vailable Columns

@ SCOTT LIBROS PRECIO @ SCOTT LIBROS TITULO

I

-

Figura 3.37. Seleccionamos las columnas a incluir en la vista

3 . El paso siguiente nos permite introducir un nombre para cada columna de la vista, en sustitucih de 10s nombres de las columnas originales. TambiI5n puede alterar el orden de las columnas arrastrando y soltando.

4. La pendtima operaci6n ser6 definir las condiciones de selecci6n de 10s datos. Arrastre desde el panel de la izquierda la columna IDEDITORIAL hasta el de la derecha. Haga clic en I5ste con el b o t h secundario del rat6n y cambie a la vista SQL para poder completar la condici6n SCOTT. EDITORIALES IDEDITORIAL = SCOTT. LIBROS . EDITORIAL. Pulse el b o t h Siguiente.

.

5. Como a1 crear las tablas, el ultimo paso es simplemente de confirmacidn. En I51 podemos ver la sentencia SQL con la que va a generarse la vista. No tenemos m6s que pulsar el b o t h Terminar para crearla. Para ejecutar la vista, y ver el resultado, seleccihela, en el panel derecho, haga clic sobre ella con el b o t h secundario del rat6n y elija la opci6n View Contents. Deber6 encontrarse con una ventana como la de la figura 3.39. Ldgicamente, puede modificarla para afiadir criterios adicionales de seleccibn, en la cl6usula WHERE, con el objetivo de filtrar las filas y obtener s610 las que cumplan ciertas condiciones.

Definir funciones y procedimientos almacenados Como vimos en el capitulo anterior, en Oracle podemos crear procedimientos almacenados, que pueden tomar par6metros per0 no devolverlos, y funciones, que

Programacidn de bases de datos con Visual Basic .NET

si pueden devolver valores como resultado. Comencemos definiendo la funcibn propuesta como ejemplo a1 final del capitulo previo.

Summary Name LIBROSPOREDITORIAL Schema SCOTT

r ModifyView Definition This wll override the view deflnltion specifled in the prevlous pages Of the wizard i _ l _ _ _

K E z E VIEW SCOTT "LIBROSPOREDITORIAL A5 8 seldit SCOTTEDITORIALES NOMBRE as Editurlal , SCOTTLIBRI TITULO as Titilo SCOTT LIBROS PRECIO as Prerio' froin SCOTT EDIT~RIALES.SCOTT LIBROS j \VHERE (SCOTT EDITOPIALES IDEDITORIAL= SCOTTLIBROS E WTH RE4D ONLY

I

1

, I

__

Ayuda

Can ce Ia r I _

__

-

, - Anterior -

I

1

(r)

a

Figura 3.38. Resurnen de la creacion de la vista

~

Editorial Lpress

C. Tituln Cl,rr

4 Interraw Design lor Frngrammers

Preriu

C.

31

,Anaya Multimedia

SQL Server 2000

1075

(Anaya Multimedia

Guia practica para usuarios JBuilder 7

1075

IAnaya Multimedia

Programacion con Visual CX NET

39

(Anaya Multimedia

Programacion convisual Studio NET

40

jAnaya Multimedia

Programacion conVisual Basic NET

39

jAnaya Multimedia

Guia practica para usuarios deVisual Basic NET

10 75

{Anaya Multimedia

Guia practica para usuarios de Visual Studio NET

1 0 52

IAnaya Multimedia

Programacion con Delphi 6 y Kyllx

37 26

'Anaya Multimedia

Guia practica para USuariOS de Delphi 6

1052

IAnaya Multimedia Anaya Multimedia

Manual avanzado Excel 2002

jAnayaMultimedia Anaya Multimedia

Guiapractica para usuarios de Kyllx lntroduccion a la programaclon

I

i I

21 04 L

Guia practica para usuarios de Excel 2002

__ _

_

1052

_

1 0 5__ 2 - _24 04

I -.

I

Figura 3.39. Resultado de ejecutar 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

1. Introducir en la parte superior el nombre de la funcidn, NUMTITULOS en este caso.

2. Seleccionar el esquema donde se alojar6 la funcih, en este caso SCOTT. 3. Escribir el c6digo de la funci6n en el apartado Source, exceptuando la cabecera CREATE FUNCTION NUMTITULOS que ya se da por asumida. Es decir, dejaremos la pareja de parentesis con el pardmetro de entrada y el resto del c6digo.

A1 pulsar el b o t h OK se compilar6 el c6digo y crear6 la funci6n. Seleccione la carpeta FunctionsSCOTT para localizarla y compruebe que en la columna de la derecha aparece la indicaci6n Valid. De no ser asi, haga doble clic sobre la funcibn, para abrir la ventana mostrada en la figura 3.40, y corrija cualquier error que pudiera existir en el c6digo. Pulsando el b o t h Compile podr6 saber si la funcion es v6lida 0,por el contrario, contiene errores.

itorla

IN INTEGER IIEFALlLT 0)

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:

Figura 3.40. Crearnos la funcion NUMTITULOS

Esta funci6n devuelve un resultado unico. Si queremos crear un procedimiento almacenado que haga lo mismo, lo cual es perfectamente posible, tendremos que utilizar un par6metro de salida, de tip0 OUT, asign6ndole el valor a devolver en lugar de utilizar la sentencia RETURN. Si lo que pretendemos devolver no es un valor unico, como en este caso, sin0 un conjunto de datos resultante de una consulta, como hicieramos en el segundo pro-

Prograrnacion de bases de datos con Visual basic .NET

cedimiento almacenado escrito con Transact-SQL, el tema se complica algo mds, ya que en PL/SQL no podemos, sin mtis, ejecutar algo asi: CREATE PROCEDURE NUMTITULOSEDITORIAL IS BEGIN SELECT E.NOMBKE, COUNT(L.TITUL0) NTJMTITULOS FROM SCOTT.EDITORIALES E, SCOTT.LIBROS L WHERE E.IDEDITOKIAL = L.EDITORIAL GROUP BY E.NOMBRE; END;

A pesar de que la consulta estd expresada correctamente, podemos ejecutarla en SQL*Plus y obtenemos el resultado esperado, a1 intentar introducirla en un procedimiento almacenado obtenemos un error de compilaci6n. En PL / SQL no puede ejecutarse una consulta y esperar que vuelva automtiticamente a1 proceso que ejecute el procedimiento almacenado, como si ocurre con Transact-SQL. La soluci6n pasa por recoger el resultado de la consulta en una variable, una referencia a un cursor, y esperar que el proceso que invoque al procedimiento haga con dl lo que le interese. Para esto es necesario dar dos pasos: crear un paquete PL/SQL en el que se defina un nuevo tipo de dato asociado a REF CURSOR, por una parte, y codificar el procedimiento almacenado de tal manera que emplee ese tip0 para devolver el resultado. Localice la carpeta Package en el panel izquierdo del Oracle DBA Studio, abra el men6 emergente y seleccione la opci6n Create. Introduzca LIBROSPKG como nombre, elija SCOTT como esquema de destino e introduzca, como se aprecia en la figura 3.41, la definici6n del nuevo tipo, a1 que llamaremos rs. El paquete contendrti s610 esto, la definici6n del tipo. A continuacion definiremos el procedimiento almacenado, seleccionando la opcion Create de la carpeta Procedure. Introducimos el nombre del procedimiento, NUMTITULOSEDITORIAL, elegimos SCOTT como esquema y escribimos el c6digo siguiente: (Resultado OUT LIBROSPKG.RS) IS BEGIN OPEN Resultado FOR SELECT E.NOMBRE, COUNT(L.TITULO) NUMTITULOS FROM SCOTT.EDITORIALES E, SCOTT.LIBR0.S L WHERE E.IDEDITORIAL = L.EDITORIAL G R O I J P BY E.NOMBRE; END;

Observe c6mo se indica que existe un pardmetro de salida, cuyo tip0 es el definido previamente en el paquete LIBROSPKG.Fijese tambidn en c6mo se inserta el resultado 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

Figura 3.41. Definicion del paquete con el tipo de dato rs

~

_

_

_

_

_

_

_

~

^

_

~ . - I I _ _ - ~ ---I_I_

-

En este momento contamos con una funci6n y un procedimiento almacenado que, en principio, aparecen como vblidos, ya que no han generado errores a1 guardarse en la base de datos. No sabemos, sin embargo, como funcionan ni si el resultad0 obtenido es el que se cspera, para ello tendremos que ejecutarlos. Con este fin tendremos que recurrir a la herramienta SQL*Plus Worksheet, seleccionbndola del grupo Database Administration de la lista de programas de Oracle. Deberb introducir el nombre de usuario, clave de acceso y nombre del servicio con el que va a conectar, que en este caso Serb LIBRos. Comencemos ejecutando la funci6n NUMTITULOS, para lo cual tendremos que declarar una variable, guardar el resultado y despues mostrarlo en el panel inferior. Esto es lo que hemos hecho en la figura 3.42, en la que hemos usado la palabra clave VARIABLE para declarar la variable, en vez de abrir una secci6n DECLARE seguida de un bloque BEGIN/ END. El resultado, como se aprecia en la parte inferior, es el ntimero de titulos devuelto por la funci6n. Para ejecutar el procedimiento almacenado NUMTITULOSEDITORIAL hemos de tener en cuenta que, a diferencia de lo que ocurria en Transact-SQL, no bastarii con llamarlo mediante la sentencia EXECUTE. Es precis0 pasar un parbmetro, concretamente una variable capaz de guardar una referencia a un cursor. Por lo tanto declararemos una variable de tip0 REFCURSOR, entreghdola como par5metro al

I

Programacidn de bases de datos con Visual Basic .NET

procedimiento almacenado. Despuks, no tenemos m6s que imprimir dicha variable para poder ver el resultado, como se aprecia en la figura 3.43. En un capitulo posterior veremos c6mo acceder a estos datos desde una aplicaci6n escrita con Visual Basic, utilizando 10s servicios de ADO.NET.

Procedimiento P L m L terminado correctamente.

Figura 3.42. Ejecucion de la funcion N U M T I T U L O S en SQL*Plus Worksheet

En realidad, el procedimiento almacenado que hemos creado como ejemplo es simplemente eso, un ejemplo, ya que en la practica, puesto que no se efectua ningun proceso especial de la inforrnacion, resultaria mucho mas facil crear una vista que generase el mismo resultado. 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

especialmente si nuestras necesidades de almacenamiento y gesti6n de datos no son las de una gran empresa. De ser asi, podemos evitar gran parte de la complejidad de Oracle optando por un producto de menor nivel. Existen muchos otros RDBMS multiplataforma, para varios sistemas operativos, aparte de Oracle, por ejemplo el popular MySQL o InterBase.

Figura 3.43. Recuperamos la referencia al cursor devuelto por el procedirniento almacenado

InterBase es un producto adquirido por Borland hace aiios a la empresa AsthonTate, la misma que cre6 dBase. Tras diversos vaivenes, InterBase actualmente es el RDBMS de Borland y es ampliamente utilizado por aquellos que emplean las herramientas de desarrollo de dicha empresa, entre ellas el conocido Delphi, C++ Builder y Kylix. A pesar de sus posibilidades, InterBase es un RDBMS ligero, de pequefio tamafio, y f6cil de instalar, distribuir y configurar. Como todos 10s RDBMS, cuenta con una parte que a c t ~ como a servidor y otra que es el software a instalar en 10s clientes para comunicarse con ese servidor. Ambos pueden instalarse, indistintamente, en Windows, Linux y Solares. Actualmente existen dos versiones de InterBase independientes. Una tiene una licencia de software libre, sin coste per0 sin soporte alguno ni garantia por parte

Programacidn de bases de datos con Visual Basic .NET

de Borland, y la otra es el product0 comercial que vende esta empresa. La primera es InterBase 6.0 y la segunda InterBase 6.5. Puede obtener la primera de http : / / mers . com, tan s610 tiene que pulsar sobre el sistema operativo que desea, descargarla e instalarla. Si desea probar InterBase 6.5, puede obtener una edici6n trial de http://www.borland.com/products/downloads/download~interbase. html. En 10s puntos siguientes se utilizar6 la versi6n 6.5 instalada sobre un sistema Windows XI' Professional. Esta incorpora una herramienta, llamada IBConsole, que simplifica la mayoria de las operaciones que, en versiones previas a la 6.0, tenian que efectuarse necesariamente mediante sentencias SQL. Abra el grupo de programas InterBase y seleccione la o,pcion IBConsole, deberi encontrarse con una interfaz como la de la figura 3.44. Esta seri el punto de partida para las operaciones descritas en 10s puntos siguientes. IBCorrsole onsole Yiew sewn Database Iools -

Help

ctwn

Ifserver' Local Server

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

6 objeck latec

Figura 3.44. Aspect0 de la herramienta IBConsole recien puesta en marcha

Habitualmente IBConsole se utiliza en el mismo ordenador donde se ha instalado InterBase y, a1 iniciarse, ese servidor aparece ya como Local Server. De no ser asi, pulse el primer b o t h que aparece en la parte superior, el que est6 m6s a la izquierda, para registrar el servidor local o un servidor remoto en caso de que este usando IBConsole desde una m6quina diferente. Teniendo seleccionado el servidor, en el panel izquierdo, haga doble clic en el derecho sobre la opcion Login para iniciar sesi6n. Aparecerfi un pequefio cuadro

de dialog0 en el que debe introducir el nombre de usuario y la clave. Si no ha creado una cuenta especifica para su trabajo, puede utilizar la cuenta SYSDBA con la clave por defect0 masterkey. Una vez se haya iniciado sesibn, podr6 desplegar el contenido de Local Server y ver que hay diferentes carpetas: Databases, Users, Certificates, etc. La carpeta Databases esta inicialmente vacia ya que no hemos creado base de datos alguna. Haga clic con el b o t h secundario del rat6n sobre dicha carpeta y elija la opci6n Create database. Aparecera un cuadro de dialog0 en el que debe introducir tres datos: El camino y nombre del archivo, u archivos, en el que residir6 la base de datos. En nuestro caso sera un solo archivo llamado Libros . gdb. 0

El tamaiio inicial del archivo, expresado en paginas. Vamos a introducir el valor 2 5 0. El alias o nombre con el que se conocera la base de datos internamente, en IBConsole.

En la figura 3.45 puede ver 10s valores introducidos. A1 pulsar el b o t h OK se procedera a crear la base de datos y, de inmediato, esta se abrir6 en IBConsole mostrando (vease figura 3.46) a la izquierda las diferentes categorias de elementos, mientras que a la derecha se enumeran las acciones posibles en ese instante.

--

I,

Server

Local Serve~

Fle(sL

Figura 3.45. Parametros de creacion de la base de datos

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

Programacidn de bases de datos con V i s u a l Basic .NET

-

@

-

*

tction

InterBaaeServers

LocalSe,ve,

- e D g l p ; Domainr Tables Indexer

4 Views &

Shied Procedures

fx

External F u n c l i ~ r

%

Generators

@

Exceptions

d

Blob Filters

3

a9 +

%

Roles

Dcrcrrplion

Disconnect

Disconnect fmm Ihe curient database

Properties

Show database propeilie~

DatabaseStalirtcs

Display databare statistics

Shutdown

Shutdown the database

Sweep

Perloim a database sweep

Tiansaction Reco

Recover limbo tiansadions

View Metadata

View Database Metadata

Dalabare Restart

Restart a database

Drop Database

Drop the curtent database

Databare Backup

Backup an InterBafe dalabare

Connected Users

V w a 1st of useif cuirently connected to the server

Rertore Databare

Hertoce an InterBare database

Backup Cert,laater seiver Log

& Urm dimension

Figura 3.46. Aspect0 de IBConsole tras crear la base de datos L i b r o s

Encontrara el archivoLibros . gdb en la carpeta de ejemplos correspondiente a este capitulo. Para utilizarla no tiene mas que copiarla a su sistema y usar la opcion Register en lugar de Create Database en IBConsole.

Para definir la estructura de las tablas tendremos que recurrir a la herramienta Interactive SQL de Interbase, que puede abrir pulsando el b o t h que tiene ese nombre en IBConsole. No hay disponibles asistentes, como en SQL Server u Oracle, por lo que tendremos que escribir las sentencias DDL y ejecutarlas. Introducimos en Interactive SQL la sentencia CREATE TABLE de la tabla E d i t o r i a1e s, que puede observar en la figura 3.47, y pulsamos el b o t h de ejecuci6n. Si todo va bien, la tabla aparecer6 en IBConsole y el c6digo SQL desapareceri. A continuaci6n escribimos la sentencia siguiente para crear la tabla L i b r o s . Observe c6mo se establece la relaci6n entre ambas tablas con FOREIGN KEY. C R E A T E T A B L E Libros 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

Figura 3.47. Creacion de la tabla Editoriales desde Interactive SQL

Tras ejecutar las dos sentencias puede cerrar la ventana de Interactive SQL. Vera 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.

En InterBase no existe un tip0 de dato con increment0 automatico. Al igual que en Oracle, no obstante, existe la posibilidad de crear una secuencia, llamada generador en el caso de InterBase, y utilizarla en un desencadenador para dar valores unicos a una columna. No obstante, en este ejemplo nos limitaremos a usar el tip0 I N T E G E R dejando que sea el usuario el que introduzca el codigo de las editoriales y libros.

Volvemos a IBConsole para proceder a la introducci6n de datos en nuestras tablas. Haga doble clic sobre la tabla Editoriales, para abrir la ventana de propie-

Programacidn de bases de datos con Visual Basic .NET

dades, y luego seleccione la pdgina Data. En ella puede, como se aprecia en la figura 3.48, introducir 10s datos de las editoriales, sin olvidar asignar a cada una de ellas un c6digo cinico.

i

1

IDependenclesI

I

Piopeillas Meladala Peirnisslons Data

P

901 Grayson Stieet

3 Apress

.

b

i

+

-

r

C

Comnt h Relresh

Figura 3.48. Desde IBConsole podemos acceder al contenido de las tablas y editarlo

Siguiendo el mismo procedimiento, proceda a insertar algunas entradas en la tabla L i b r o s . Recuerde que puede utilizar la base de datos del CD-ROM que acompafia a1 libro. Si introduce un c6digo de editorial inexistente obtendrd un mensaje de error como el de la figura 3.49. Algo similar ocurrird si da a dos libros el mismo identificador, infringiendo otra de las restricciones.

l

L



I

Figura 3.49. Error generado al introducir un codigo de editorial inexistente

~

_

I

_

_ I

A1 igual que para definir las tablas, tendremos que recurrir a la herramienta Interactive SQL para crear la vista L i b r o s E d i t o r i a l . Introduzca el c6digo siguiente y pulse el b o t h de ejecuci6n. CREATE VIEW LibrosEditorial AS SELECT E.Nombre, L.Titulo, L. Erecio FROM Editoriales E, Libros L WHERE E.IDEditoria1 = L.Editoria1

La vista es exactamente igual a la definida en 10s puntos previos usando TransactSQL y PL/SQL. Como ya sabe, puede afiadir condiciones adicionales, si asi lo desea, para filtrar 10s datos y obtener s610 parte de las filas. Para ver el resultado vuelva a IBConsole, haga doble clic sobre la vista, en la carpeta Views, y abra la p6gina Data para ver el resultado. Seri similar a1 mostrado en la figura 3.50.

1 ProDertlesI Metadata I Permissions

Data

I DeDendenciesI ~PRECIO Use! Interlace Design loi Programmers

SOL Server 2000 Guia practica para usuarios JBuilder 7 ProgramacionconVisual CU NET Programacton conVisual Sludio NET ProgiarnaciClnconVisual Basic NET Guia praclica para U S U ~ ~ I Ode S Visual Basic NET Guia precticaparaUSUMIO~deVirudStu~o NET Programacdn con Delphi 6 y Kylix Guia pdctica paia usuaiios de Delphi 6 Manual avanzado Excel 2002 Guia pdctoa paia usuarios de Excel 2002 Cluia pidctica para usuarios de Kylix Inlroducci6n a la progiarnacion Manual del microproceradot 80386

I

31 1075 1075 39 40 39 1075 1052 37 26 1052 21 04 1052 1052 24 04 40

Figura 3.50. Ejecucion de la vista desde IBConsole

En lugar de volver a IBConsole, tambien puede ejecutar la vista desde Interactive SQL con una Sentencia cOmO SELECT * FROM L i b r o s E d i t o r i a l . El conjunto de datos resultante aparecera en la parte inferior de la ventana.

La sintaxis para definir procedimientos almacenados en InterBase es ligeramente diferente a la de Transact-SQL o PL/SQL, como seria de esperar a1 tratarse de un product0 RDBMS de otro fabricante. Los procedimientos almacenados de InterBase pueden devolver valores, en realidad varios si bien tan s610 uno de ellos, con el nombre RETVAL, actua como verdadero valor de retorno. Los parimetros de entrada se declaran entre parkntesis, detris del nombre del procedimiento almacenado, y no pueden tener valores por defecto.

Programacidn de bases de datos con V i s u a l Basic .NET

Cada una de las sentencias de un procedimiento almacenado InterBase debe finalizar con un punto y coma. Esto es tambien cierto en Oracle. El problema es que la herramienta Interactive SQL identifica ese mismo carficter como final de sentencia, de tal forma que, a1 encontrarlo, da por terminada la ejecuci6n y, consecuentemente, el procedimiento almacenado no se crea apropiadamente. Para solucionar este problema, es necesario utilizar la orden S E T TERM a fin de cambiar el finalizador ; por otro carscter, restituyhdolo a1 terminar. Comencemos definiendo el procedimiento N u m T i t u l o s que, como en 10s casos anteriores, debe facilitar el numero total de titulos o 10s de una cierta editorial en caso de facilitarse su c6digo. Introduzca el cddigo siguiente en la herramienta Interactive SQL y ejecutelo. SET TERM # ; CREATE PROCEDURE NurnTitulos(CodEditoria1 INTEGER) RETURNS (RETVAL INTEGER) AS BEGIN IF [CodEditorial = 0 ) THEN SELECT COUNT (ISBN) FROM Libros INTO : RETVAL; ELSE SELECT COIJNT (ISBN) FROM Libros WHERE Editorial = :CodEditorid1 INTO :RETVAL; SUSPEND; END#

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 procedimiento 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 devoluci6n 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 variables como columnas sigan a la clfiusula SELECT, introduciendo 10s valores extraidos 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

;

#

Con esto ya tenemos creados nuestros dos procedimientos almacenados. De forma similar podria crear otros m& sofisticados, incluyendo, aparte de condicionales simples y consultas, bucles y otras operaciones sobre las tablas de la base de datos.

Como comprobaci6n, puede ejecutar 10s procedimientos almacenados recikn creados desde la propia herramienta Interactive SQL. Solo tiene que introducir una sentencia S E L E C T * FROM seguida del nombre del procedimiento almacenado y, en el caso de N u m T i t u l o s , incluyendo 10s parAmetros necesarios. En la figura 3.51 puede ver la ejecuci6n del procedimiento NumTitulosEdit o r i a l , mostrando en la parte inferior 10s resultados. Estos son idhticos a 10s obtenidos en 10s ejemplos de SQL Server y Oracle.

Figura 3.51. Ejecucion del procedimiento almacenado NumTitulosEditorial

Oracle, SQL Server e InterBase comparten el hecho de ser sistemas relacionales de gesti6n de datos, o bien RDBMS, guardando algunas similitudes con Microsoft Access que, a pesar de ser un sistema de datos de escritorio, no un RDBMS, tam-

bi6n se usa para almacenar informacion estructurada y utiliza el lenguaje SQL. No toda la informacion con la que tiene que trabajar una aplicaci6n est6 siempre estructurada como hemos visto en 10s puntos anteriores, en algunas ocasiones pueden ser datos mas o menos organizados en documentos, por ejemplo hojas de c6lculo Excel, datos en documentos XML e, incluso, informacion jerarquica como la que gestiona el Directorio activo de Windows 2000 y Windows .NET. Microsoft Excel es una aplicacion muy extendida, tanto o mas que Access, siendo empleada por todo tip0 de usuarios para gestionar sus datos, efectuar c6lculos sobre ellos, representaciones graficas, etc. Esta herramienta estructura la informaci6n en libros, cada uno de 10s cuales se compone de paginas que, a su vez, est6n formadas por celdillas. Desde ADO.NET es posible acceder a estos documentos como si de bases de datos se tratasen, por lo que vamos a preparar una hoja de c6lculo Excel que utilizaremos como origen de datos en capitulos posteriores. i

A1 iniciar Microsoft Excel se encontrar6 ya con un nuevo libro en blanco, mostrando la interfaz una apariencia similar a la que aparece en la figura 3.52. El libro tiene un nombre por defecto, L i b r o 1,y cuenta inicialmente con tres paginas llamadas Hoj a l , H o J a 2 y H o J a3, a las que puede acceder utilizando las pestanas que aparecen en la parte inferior de la ventana. Observe que el area central tiene el aspect0 de una cuadricula, identificindose cada columna con una letra y cada fila con un numero. El cruce de cada columna con cada fila es una celdilla, identificada por la letra de columna y nLimero de fila, por ejemplo D5. A un conjunto de multiples filas adyacentes, a lo largo de varias filas y / o columnas, es a lo que se llama rungo. Haga clic sobre el b o t h que muestra el icono de un disquete. Apareceri el tipico cuadro de dialogo para guardar archivos. D6 el nombre L i b r o s . xls a1 libro. Ya tiene creado el equivalente a una base de datos vacia.

Nota En la carpeta de ejemplos de este capitulo encontrara el archivo L i b r o s . xls tal y como quedaria al final del proceso que va a describirse en 10s puntos siguientes.

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 describen 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

Figura 3.52. Apariencia de Microsoft Excel al iniciarse

Haga clic con el b o t h secundario del rat6n sobre la pestafia Hoja3, en la parte inferior del libro, y luego seleccione la opci6n Eliminar. Responda afirmativamente, pulsando el b o t h Aceptar, a1 aviso de que el borrado serd permanente. Haga doble clic sobre la pestafia Hojal . Verd que aparece un cursor que le permite modificar su nombre. Lldmela Editoriales. Repita el paso anterior con la Hoja2 llamdndola Libros. Desplace el cursor de la hoja Editoriales hasta la celdilla A?, en realidad ya deberia estar alli si no lo movi6 antes, y escriba el texto IDEditorial, pulsando Intro a1 final. Muevase a la colurnna de la derecha, a la celdilla BI, y escriba Nombre. Repita la operaci6n escribiendo Direction en C1. De esta manera ha definido las tres columnas con que contard cada fila correspondiente a una editorial. En este momento el libro deberia tener el aspect0 que puede verse en la figura 3.53. Siguiendo la misma linea, escriba a continuacih en las celdillas A1 a F1 de la hoja Libros 10s titulos IDLibro, ISBN, Titulo, Autor, Editorial y Precio.

Prograrnacidn de bases de datos con Visual Basic .NET

Completados estos pasos, tenemos un libro Excel con una estructura similar a las tablas creadas previamente en Oracle o Access. Como habra observado, no hemos 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 contenido 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 introducir 10s datos, sin mds. En el punto anterior, a1 escribir 10s titulos de las columnas, ya hemos introducido varios datos en cada una de las hojas del libro, aunque esos datos fuesen 10s titulos o nombres de las propias columnas. Usando exactamente el mismo m4todo escribiriamos la informacih de cada fila, 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 1 IDLibro ISBN 2 1 1 853115 94 1 3 2 84415 1136 5 4 3 84415 13243 5 4 84415 1392 9 6 5 84415 1376 7 7 6 84415 1351 1 8 7 81415 1290 6 9 8 81 415 12914 10 9 84415 1261 2 11 10 84 415 1255 8 12 11 84415 1230 2 13 12 84415 1202 7 14 13 84 415 1132 2 15 14 81415 11454 16 15 84 7615 234 5 17

n

Tilulo User Interface Design for Programmers SQL Server 2000 Guia practica para usuarios JBuilder 7 Programaclon con Visual C# NET Programacion con Visual Studio IlET Programacion con Visual Rasic NET Guia practica para usuarios de Visual Basic NET Guia practica para usuarios de Visual Studio PIET Programacion con Delphi 6 Kvlix Guia practlca para usuarios de Delphi 6 Manual a*,anzado Excel 2002 Guia practica para usuarios de Excel 2002 Guia practica para usuarios de Kylix lntroduccion a la programacion Manual del microprocesador 80386

D

E

F

Autor Editorial Precio 3 31 Joel Spolsky 1 1075 Francisco Charte 1 1075 Francisco Charte 1 35 Francisco Charte 1 40 Francisco CharteiJorge Serrano 1 39 Francisco Charte 1 10 75 Francisco Charte 1 10 52 Francisco Charte 1 37 26 Francisco Charte 1 10 52 Francisco Charte 1 21 04 Francisco Charte 1 10 52 Francisco ChattelM Jesus Luque 1 1052 Francisco Charte 1 24 04 Francisco Charte 2 40 Chris H Pappas&William H Murray Ill

:

-

Figura 3.54. lntroducirnos varias filas de datos en la hoja Libros de Excel

Para ajustar automaticamente el ancho de cada columna al apropiado para mostrar su contenido, situe el punter0 del raton entre la division de dos columnas en la fila de encabezado, por ejemplo entre las columnasA y B. En ese momento el cursor cambiara de apariencia, indicandole que puede pulsar el boton principal del raton y arrastrar para modificar el ancho de la columna. Haga doble clic para dejar que sea el propio Excel quien efectue el ajuste.

Usando las opciones de Excel podriamos, a partir de 10s datos introducidos, buscar autom6ticamente el nombre de la editorial a partir del c6digo que hay en la hoja Li bros, creando referencias en una nueva hoja que, en la prActica, funcionaria como una vista dinimica de 10s datos existentes en el libro. No obstante, para no extendernos en un campo que no es especificamente el que m6s nos interesa, nos limitaremos a guardar el libro dejindolo preparado para su us0 en un capitulo posterior.

Programacidn de bases de datos con Visual Basic .NET

Los libros de Excel se almacenan en un formato especifico creado por Microsoft para este producto. A pesar de que existen filtros en algunas aplicaciones para poder utilizar su contenido, lo cierto es que el intercambio de informaci6n con otras aplicaciones y sistemas es limitado. Lo mismo ocurre con la representaci6n interna de 10s datos de todos 10s RDBMS, sin excepcibn, tanto fisicamente en disco como en memoria a1 transferir 10s datos desde el servidor a 10s clientes. El lenguaje XML naci6, precisamente, con el objetivo de facilitar el intercambio de informaci6n salvando las barreras en que se convierten en ocasiones las diferencias de plataforma, sistema operativo, lenguajes, etc. Basado en SGML, el lenguaje XML se caracteriza, como su propio nombre indica, por ser extensible, lo que significa que podemos crear nuestras propias marcas segun las necesidades de cada caso. ADO.NET utiliza XML como formato de representaci6n interna de 10s conjuntos de datos, formato que tambien emplea a la hora de transferir la informaci6n entre miiquinas, independientemente de que el origen de datos sea un RDBMS, un libro Excel o cualquier otro posible. Guardar 10s datos en formato XML y recuperarlos posteriormente, como veremos en su momento, es muy simple. En 10s dos puntos siguientes, por tanto, nos centraremos tan s610 en la aportaci6n de algunos fundamentos sobre XML.

_

I

_

_

_

I _ I _ _

_

~

_

_

_

_

-

~ _ _~ _~ ~ - .-_-^ _ ~__

_ _

____ - - -__ - I

La estructura de 10s documentos XML se define mediante esquemas XML, tambien conocidos como esquemas XSD. Realmente, un esquema XSD es un documento XML que sigue unas reglas preestablecidas por el W3C, usando marcas especificas para la definici6n de tipos y elementos que deben existir en el documento. Para crear un esquema XSD, a1 igual que para editar cualquier documento XML, no necesitamos miis que un editor simple de texto, como podria ser el Bloc de notas. No obstante, como usuarios de Visual Studio .NET tenemos a nuestro alcance herramientas mucho miis sofisticadas, herramientas que pueden ahorrarnos la edici6n manual de este tip0 de archivos. Vamos a emplearlas para crear el esquema XSD del documento XML que crearemos posteriormente. Partiendo de un proyecto vacio, abra el cuadro de diiilogo Agregar nuevo elemento y, de la carpeta Datos, seleccione Esquema XML, como se muestra en la figura 3.55. Introduzca en la parte inferior el nombre del archivo donde se alojarii el esquema, Libros x s d en este caso. En la superficie de trabajo aparecerii una indicacion comuniciindonos que podemos arrastrar y soltar componentes para comenzar a disefiar. Observe que en la parte inferior aparecen dos botones: Esquema y XML. Si pulsa este ultimo verii la definici6n textual del esquema que, a medida que lo disefiemos visualmente, irii actualiz6ndose. Tome del Cuadro de herramientas un complexType e insertelo en

.

3 . Origenes de datos

cualquier punto del Brea central. AparecerB un recuadro con dos columnas. Introduzca 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 figura 3.56 puede ver c6mo se han definido las tres columnas necesarias para registrar las editoriales.

I/

Categorias:

Plantillas:

Archivo XSLT Anstente para

formulanos

I

...

-

-

Arc%wo para crearun esquemi para documento; XML Nombre

___

ILibros xsd Cancelar

I

Ayuda

1

Figura 3.55. AAadimos al proyecto un esquema XML Cuadro de herraKeEtas IwuemaXML

4

-

B K -_-A

Punter0 element attribute

a

attributeGroup compbxType simpleType

EZ group El any anyAttrlbute facet

D

clave

% Relation

I

,

IDEditorial Nombre Direccion

integer string string

I

I I I

Figura 3.56. Definicion del tipo complejo Editorial

Aiiada un nuevo tip0 complejo, 1lamBndole L i b r o , y defina el nombre y tip0 de cada una de las columnas, tomando como referencia el libro Excel del punto anterior o cualquiera de las bases de datos creadas a mod0 de ejemplo.

Programacidn de bases de datos con Visual Basic .NET

El ultimo paso ser6 la inserci6n en la superficie de un e l e m e n t , a1 que llamaremos L i b r o s . La diferencia entre un c o m p l e x T y p e y un e l e m e n t es la misma que existe entre la definici6n de una estructura de datos y la declaraci6n de una variable. E d i t o r i a l y L i b r o son tipos de datos, a partir de 10s cuales se pueden crear otros o bien declararse variables que, en el entorno XML, se conocen como elementos. Nuestro elemento L i b r o s estar5 compuesto de dos subelementos: E d i t o r i a l e s y L i b r o s . El primer0 de ellos seria de tip0 E d i t o r i a l y el segundo de tipo L i b r o . De esta forma, el elemento L i b r o s hace las veces debases de datos, mientras que 10s subelementos indicados serian las tablas que habria en su interior. Visualmente el esquema quedaria como puede apreciarse en la figura 3.57. El c6digo del esquema es el siguiente: < ? xml v e r s i o rI= " 1 . 0 " e n c o d i ng= " u t f- 8 "

?>

< x s :s c h e m a i d = " L i b r o s " targetNamespace="http: //tempuri. o r g / l i b r o s . xsd" e 1eme rl t Fo rmDe f a u 1t = " q u a I i t i ed " xml r, s = " ht t p : / / t e m p u r i . c) r g / L i bro s . x s d xmlns:mstns="http://tempuri . o r g / L i b r o s . x s d " x m l n s : x s = " h t t p : / /www.w3. org/2001/XMLSchema"> < x s :complexType n a m e = " E d i t o r i a l " >

< x s : e l e m e n t name="Nombre" t y p e = " x s : s t r i n g " / > < x s : element n a m e = " D i r e c c i o n " t y p e = " x s : s t r i n g " / >

< x s : complexType n a m e = " L i b r o " > < x s :s e q u e n c e >

< x s : e l e m e n t name="ISBN" t y p e = " x s : s t r i n g " / > < x s : e l e m e n t narne="TItulo" t y p e = " x s : s t r i n g " / >

< x s :e l e m e n t n a m e = " E d i t o r i a l " t y p e = " x s : i n t e g e r " / >

< / x s :s e q u e n c e >

< x s :e l e m e r i t n a m e = " L i b r o s " >

< x s :s e q u e n c e >

< / x s :c o m p l e x T y p e >

.

Guarde el documento L i b r o s xsd, esquema que, alojado en un archivo independiente, serviri para establecer la estructura de 10s documentos XML que actuarian 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

J--l-G

Generar

pepurar

X Q .

Ezquema

@*

nerramientas

VeEtana

Ayuda

t Debug

q%. Jadro de herramtentas 4 X

Libros.xrd*

I

,quema XML

4

Funtem

b

E element A attribute

Libros Edtoriales

(Libros) Editorial

Libror

Libra

1

#

attributeGroup E+ complexType

%

any

)a, anyAttribute F facet

D

clave

&

Relation

(Fredetermmado) (Predetermmado) (Fredetermmado)

abstract block COrnplexType default

(Predetermmado) (Fredetermmado) 4 x 5 COmpleXType >

final fixed form

(Predetermmado)

I

5lmpleType

G group 0

Casesensitive IsDataSet Locale

Edtoriales

Editorial

Libros

Libro

$

3

(Predetermmado)

id key

(Colecclo")

name

Libros

nillable

(Fredetetmmado)

rubsttutionGrat type

ntllo del Fortapapeles

(Libros)

Varlos

Figura 3.57. Aspect0 visual del esquema XML en el entorno de Visual Studio .NET

Nota En este ejemplo el esquema XSD utiliza el espacio de nombres h t t p : / / tempuri . org/,usado habitualmente durante pruebas. En la practica, habria que sustituirdicho espacio por la referencia correcta donde se encuentre el esquema.

-

-_________ Partiendo del esquema anterior, crear un documento XML que se ajustase a su ---

"--

-

___x

-

-__^(

I

X I -

____

---___.-ll-__X

-____I_-

I

I

estructura es bastante fAcil. El documento contendria un elemento raiz llamado L i b r o s que, a su vez, tendria dentro 10s elementos E d i t o r i a l e s y L i b r o s , compuestos cada uno de ellos de las columnas que contendrian 10s datos reales, tales como identificadores, nombre de la editorial, ISBN del libro, etc. Abra de nuevo el cuadro de diAlogo Agregar nuevo elemento y, en esta ocasibn, seleccione de la carpeta Datos el elemento Archivo XML, introduciendo en la parte

Programacio'n de bases de datos con V i s u a l Basic .NET

inferior el nombre del archivo, por ejemplo L i b r o s . xml. A1 pulsar Abrir se encontrarii en el editor de Visual Studio .NET con un documento compuesto de una sola linea:

Esta linea indica simplemente que el archivo es un documento XML, comunicando el conjunto de caracteres en que se encuentra codificado. Acceda a la ventana Propiedades y despliegue la lista que hay adjunta a la propiedad targetschema. Seleccione el elemento http: //tempuri.o r g / L i bros xsd, referencia a1 esquema que hemos creado en el punto anterior. En el editor apareceri, bajo la anterior, la linea siguiente:

.

< / L i b r o s >

Ya tenemos la marca que actua como raiz de todo, como si fuese el inicio de la base de datos, asi como la marca de cierre . Aunque podriamos ir introduciendo 10s datos manualmente, el editor de Visual 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 hacerlo nos encontramos con una interfaz como la de la figura 3.58, en la que podemos 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 programaci6n. Es, por tanto, el recurso ideal para el intercambio de informacih.

< L i b r o s xmlns="http: //tempuri.org/Libros .xsd">

l 5 < / IDLibro> ?ISBN>84-7615-234-5 Manual d e l microprocesador 80386 Chris H.Pappas&William H.Murray, IIIC/Autor> 2 40

l 24.04

l3 84-415-1132-2

Guia prictica para usuarios d e Kylix Francisco Charte l l0.52

l2 l 21.04

Guia prictica para usuarios de Delphi G iAutor>Francisco Charte l CPrecio>l0.52

g CISBN>84-415-1261-2 Programacihn con Delphi 6 y Kylix Francisco Charte l 37.26

8 84-415-1291-4 Guia pr2ctica para usuarios de Visua Studio .NET Francisco Charte l l0.52

7 84-415-1290-6

Prograrnacidn de bases de datos con V i s u a l Basic .NET Guia prictica para usuarlos d e Visual Basic .NET Francisco Charte l l0.75

b 84-415-1351-1 Programacihn c o n Visual Basic .NET Francisco Charte l

4c/IDLibro> 84-415-1392-9 Programaci6n con Visual C # .NET Franc i sco C ti a r t e < / Au t o r> l 39

3 84-415-1324-4 Guia prdctica para usuarios JBuilder 7 Francisco Charte l l0.75

l 1-893115-94-1 User Interface Design for Programmers Joel Spolsky 3 3i

2 84-415-1136-5 SQL Server 2000 Francisco Charte i l0.75

l

3 . Origenes de datos

Anaya M u l t i m e d i a < / N o r n b r e > < D i r e c c i o n > J u a n I g n a c i o Luca d e Terla, 1 5 < / D i r e c c i o r i >

< E d i t o r - i a 1e s > 2E d i f i c i o Va 1r e a 1t y , 1 a p 1a rlt a < / D i r e c c i on >

< IDEdi t o r i a 1 > 3 < / I DEdi t o r i a 1> Apress < D i r e c c i o rl> 9 0 1 G r a y s o n St r e e t < / D i r e c c i n rl>

c/Libros>

&rchvo

EdKi6n

\Ler

Froyecto

senex

j LlbrOS.nml*

2 3

4 I5 6 ,7 18

19 10 111 12 113 I 14 ,15

pepwar

XML

He%rarmentas

Ventana

Aygda

I

84-4151136 5 SQL Server 2000 84 415-1324-4 Guia practica para usuarm JBuilder 84-415-1392-9 Programacioncon Visual CX .NET 84-415-13767 Programacioncon Visual Studio .NE 84-415-1351-1 Prograrnacion con Visual Basic .NET 84 415 1290-6 Guia practica para usuarios de Visua 84 415-1291-4 Guia practica para usuarios de Visua 84-415-1261-2 Programacioncon Delphi 6 y Kylix 84-415-1255-8 Guia practica para usuarios de Delp 84-4151230 2 Manual avanzado Excel 2002 84 415 1202 7 Guia practica para usuarios de Excel 84 415-1132-2 Guia practica para usuarioz de Kylix 84-415-1 145-4 Introduccion a la programacidn 84-7615-234-5 Manual del microprocerador 80386

1 1 x

Francisco Charte Francisco Charte

1 1

Francisco Charte

1

Francisco Charteilorge 5 1

10,75 10,75 39 40 39 10,75 10,52 37,26 10,52 21,04 10,52

Francisco Charte

1

Francisco Charte Francisco Charte

1 1

Francisco Charte

1

Francisco Charte Francisco Charte

1 1

Francisco Charte/M.lesu

1

Francisco Charte

1

10,52

Francisco Charte

1

Chris H.Pappas&William

2

24,04 40

Y

Figura 3.58. Introduccion de datos en el documento XML

En la carpeta de ejemplosde este capitulo encontrara 10s arChivosLibros .xsd y L i b r o s xml,conteniendo el esquema y el documento XML desarrollados

.

como ejemplo en este punto.

Programacidn de bases de datos con Visual Basic .NET

rio En la mayoria de empresas actuales, especialmente de un tamaiio medio a grande, existen redes heterogheas, diferentes sistemas y todo ello distribuido geogrdficamente 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 desarrolladores de aplicaciones. Las redes se componen de ordenadores, dispositivos independientes o asociados a un ordenador, tales como impresoras o medios de almacenamiento, grupos o perfiles, cuentas de usuario, etc. Generalmente cada sistema cuenta con un servicio 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 protocolo, bastante aceptado, para acceder a estos servicios de directorio llamado LDAP. Con el objetivo de simplificar la gestion de recursos en distintos tipos de directorio, Microsoft incluy6 en Windows 2000 Server el Directorio activo (DA para abreviar) o Active Directory. Mediante DA es posible acceder a recursos de cualquier punto de la red, sin importar el servicio de directorio subyacente del sistema con que funcionen las mdquinas. Gracias a DA, 10s administradores pueden organizar 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 relacional al estilo que hemos conocido en 10s puntos previos. En la posicih m6s alta 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 detalles sobre el funcionamiento y 10s esquemas del DA. Puede encontrar mas information sobre este servicio en h t t p : / / M S D N . M i c r o s o f t . e s .

Los administradores de sistemas acceden a1 DA mediante una interfaz de usuario tipica, similar a la que puede verse en la figura 3.59. En el panel izquierdo aparece la jerarquia de contenedores, en este caso perteneciente a un dominio llamado es t e l a r n e t , mientras que a la derecha se muestran 10s objetos que existen en el contenedor seleccionado en ese momento. Mediante operaciones de raton, seleccionando elementos y accediendo a sus respectivos menus de opciones, puede efectuarse cualquier operacidn de gesti6n.

.

3 . Origenes de datos

dS

d

v s l t a Avvda

Builtin

0Computers lc3J Domain Controllerr

0

Users i- &J EarySoft Administracion Demono

1

I

I

II

77 Figura 3.59. Herramienta de administracion del Directorio activo

Como desarrolladores, lo que m i s nos interesari es el acceso a1 DA desde aplicaciones propias. Con ese objetivo se utilizan 10s servicios ADSI, una interfaz de programacih compuesta de msltiples funciones a las que puede invocarse desde cualquier lenguaje. Ya que la mayoria de desarrolladores de datos estin habituados a emplear algun servicio de acceso a datos, una forma de simplificar el acceso a1 DA desde las aplicaciones consiste en utilizar el controlador OLE DB para DA, en lugar de llamar directamente a 10s servicios ADSI. Desde ADO.NET podemos configurar una cadena de conexi6n con cualquier controlador OLE DB, por lo que podemos usar ADO.NET para acceder a1 DA y, por ejemplo, localizar un recurso en el que est4 interesado el usuario. Un metodo alternativo, especialmente simple desde Visual Basic .NET, es usar 10s componentes D i r e c t o r y E n t r y y D i r e c t o r y S e a r c h e r del imbito S y s t e m . D i r e c t o r y S e r v i c e s . Gracias a ellos es posible efectuar todas las operaciones disponibles con ADSI per0 sin tener que llamar directamente a las funciones de esta interfaz.

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 aprendido a definir estructuras de tablas en distintas bases de datos, codificar procedimientos 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 comentado, 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 encontrar6 a continuacion de 4ste.

Con la denominacion generica ADO.NET se hace referencia a todos 10s servicios de acceso a datos disponibles en la plataforma Microsoft .NET, servicios que podemos usar desde cualquiera de 10s lenguajes de programacion capaces de producir 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 repartidos por varios imbitos con nombre que, en su mayor parte, tendr6 ocasion de conocer 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, comprendamos ficilmente su funcionamiento y raz6n de ser. Desde este nivel, relativamente 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 pena. Dichos objetivos se han llegado a alcanzar y podrian resumirse en 10s siguientes puntos: 0

0

Modelo de objetos mas simple y racional. Partiendo de unas interfaces genericas, y aprovechando las caracteristicas de orientaci6n a objetos con que cuentan todos 10s lenguajes .NET, el modelo de objetos es mucho mas simple y fticil de usar, con una curva de aprendizaje m6s suave respecto a ADO. Tambien resulta mas sencillo extender este modelo, afiadiendo nuevas clases de objetos y componentes. Representacion y transporte en formato XML. A pesar de que las ultimas actualizaciones de ADO permitian guardar 10s recordsets en formato XML, lo cierto es que la integraci6n total con este formato se alcanza en ADO.NET. La transferencia de 10s datos se efectua en formato XML e, internamente, 10s conjuntos de datos se representan como documentos XML. Esto simplifica la interoperabilidad con otras aplicaciones, a1 poder entregar y recoger datos en un formato entendido por todos 10s sistemas operativos y lenguajes. Menor us0 de recursos en el servidor. Uno de 10s grandes problemas actuales de 10s RDBMS es la capacidad que tienen para atender solicitudes de conexi6n por parte de 10s clientes, puesto que cada uno de ellos abre una o miis conexiones y su numero se encuentra limitado fisicamente por 10s recursos de la maquina. ADO.NET no utiliza cursores en el servidor y, ademas, opera usando un modelo de conjuntos de datos desconectados y comandos. Esto significa que la conexi6n se mantiene s610 el tiempo necesario para ejecutar un comando, ya sea de recuperacion o manipulaci6n de datos, trabajando el resto del tiempo sin consumir ningun recurso del servidor. El resultado es que 4ste se hace mucho mas escalable, pudiendo atender a un numero de clientes muy superior sin problemas y sin necesidad de ampliar 10s recursos.

0

0

Mejor rendimiento. El rendimiento en general de las operaciones efectuadas mediante ADO.NET es superior a1 obtenido con otros mecanismos de acceso a datos, en parte gracias a la existencia de proveedores nativos para trabajar sobre SQL Server y Oracle, donde se obtiene el mayor beneficio, asi como acceso direct0 a controladores ODBC, sin necesidad de pasar por el puente OLE DB-ODBC que afiade una capa mas y reduce la velocidad con que se efectuan las transacciones. Soluci6n global de acceso a datos. Tal y como se indicaba en la introduccibn, ADO.NET es una soluci6n global de acceso a datos, a1 hacer posible el trabajo con la mayoria de origenes de datos existentes y, a1 mismo tiempo, ser un servicio disponible para todos 10s lenguajes .NET, incluidos aquellos no desarrollados por Microsoft. Es el unico mecanismo que necesitaremos, in-

Programacidn de bases de datos con Visual Basic .NET

dependientemente de que nuestra aplicaci6n vaya a ejecutarse s610 en un ordenador de manera aislada o en una configuraci6n distribuida con servidores de datos y aplicaciones. Los cambios en ocasiones son para mejor y, en 6sta concretamente, seguramente lo serii si comparamos las caracteristicas de ADO.NET con las del sistema de acceso a datos que estemos empleando actualmente.

i6

rn

Aunque ADO.NET cuenta con un mecanismo para lectura directa de datos desde 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.

El conjunto de datos se crea en el cliente, donde estii ejecutdndose la aplicacibn, siendo su estructura totalmente independiente del origen de datos. Esto significa que el conjunto de datos seria exactamente el mismo sin importar que 10s datos hayan sido recuperados de SQL Server, Oracle, Excel o un documento XML. A partir de ese momento, la transferencia de la informaci6n alojada en el conjunto de datos se efectua siempre en formato XML. Un componente que se ejecuta en un servidor de aplicaciones, y se comunica con el RDBMS, puede enviar 10s conjuntos de datos a clientes remotos incluso si son aplicaciones que se ejecutan en otro sistema operativo distinto a Windows. La figura 4.1 representa una configuracih hipot6tica en la que el equipo central, destacado con un tamaiio algo mayor, es el servidor de aplicaciones que, funcionando con Windows, utiliza ADO.NET para acceder a un RDBMS, pongamos por caso Oracle, ejecutiindose en una miquina Unix. Una vez que el servidor de aplicaciones envia a1 de datos el comando de recuperaci6n de datos, y 6ste 10s devuelve al rimero, tenemos un conjunto de datos ADO.NET alojado en un cornponente. 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 ejemplo, con Borland Kylix funcionando en Linux.

:

4. lntvoduccidn a ADO.NET

Servidor de aplicaciones

I

t XML

I

Cliente Windows

Internet/lntranet

Cliente ligero (web)

Cliente Linux

Figura 4.1. La transferencia de 10s conjuntos de datos en formato XML abre las puertas a la interoperabilidad con clientes heterogeneos

Los conjuntos de datos son estructuras dinAmicas. Es posible insertar, modificar y eliminar informacih, operaciones que se registran temporalmente en forma de DiffGrarns. Estos sirven para resolver posteriormente con el origen de datos, generando 10s comandos apropiados de inserci6n actualizacih o eliminacidn.

En el noveno capitulo, dedicado al estudio de 10s conjuntos de datos, conocera algunos detalles sobre 10s DiffGrams.

Programacidn de bases de datos con Visual Basic .NET

Se indicaba en un punto previo que ADO.NET no emplea cursores en el servidor, reduciendo el us0 de recursos en 10s servidores de datos. Si esta acostumbrado a utilizar este elemento en sus aplicaciones, algo habitual en la mayoria de motores de acceso a datos actuales, seguramente se preguntari c6mo va a poder efectuar su trabajo sin poder crear un cursor. Tradicionalmente, las aplicaciones establecian una conexi6n con el servidor y 6ste creaba un cursor que facilitaba el acceso a 10s datos por parte del cliente. Este, mediante operaciones simples, solicitaba la fila anterior o siguiente, la inserci6n o edici6n de datos. El cursor se encargaba de bloquear 10s datos que estaban en edic i h , evitando el acceso por parte de otros usuarios, siguiendo un cierto esquema de comportamiento. El us0 de cursores, y la configuracibn de funcionamiento de esas aplicaciones, con conexidn continua con el servidor de datos, tenian sentido especialmente en 10s escenarios cliente / servidor en el que 10s clientes conectaban directamente con el RDBMS y, ademas, su numero era facilmente predecible segun el tamafio y necesidades de la empresa. La extensi6n de las tecnologias de Internet y, especialmente, las aplicaciones que se ejecutan en un cliente Web y 10s servicios Web, han modificado de manera significativa las necesidades y, por tanto, es preciso buscar nuevas soluciones. Mantener una conexi6n continua con el servidor de datos no es lo m6s apropiado y, en ocasiones, ni siquiera es posible en una red donde la conexi6n no est6 garantizada. Ademas, las aplicaciones que emplean 10s clientes suelen ser meras interfaces de usuario, sin posibilidades de acceso direct0 a un RDBMS y que dependen de componentes alojados en un servidor de aplicaciones segun la configuracibn esbozada en la figura 4.1. Tampoco es fticil anticipar el numero de clientes que existiran, especialmente en aplicaciones que no se ejecutan en una intranet corporativa sin0 a trav6s de Internet y abierta a todos 10s potenciales usuarios. Si cada uno de ellos abriese una conexi6n con nuestro servidor y crease su propio cursor de datos, posiblemente nos vi6ramos obligados a incrementar constantemente 10s recursos de la mtiquina, entre ellos la memoria. Frente a estos nuevos problemas, ADO.NET ofrece soluciones como el trabajo sin conexi6n continua y 10s conjuntos de datos sin conexi6n. La conexi6n con el servidor de datos es transitoria, s610 durante el tiempo preciso para ejecutar un comando y obtener el correspondiente resultado. Este se transfiere a1 servidor de aplicaciones o cliente, dependiendo de ddnde est6 ejecutkdose ADO.NET, y a partir de ese momento se opera sobre un conjunto de datos sin conexi6n. Las acciones tipicas sobre el cursor, como el desplazamiento por las filas, se efectua de manera inmediata en el cliente, sin tener que enviar una solicitud a1 servidor y esperar la respuesta ni, por supuesto, consumir recurso alguno en el servidor. Si todas las acciones se efectuan sobre un conjunto de datos sin conexibn, ic6mo se actualiza la informaci6n en el servidor? En el modelo cliente servidor, segun

4 . Introduccidn a ADO.NET

decia antes, era el propio cursor el que se encargaba de ir bloqueando y gestionando 10s conflictos entre clientes. En ADO.NET se generan comandos de actualizaci6n de forma dinarnica, enviandose a1 servidor cuando es necesario consolidar la informacibn. En caso de conflicto, se obtiene una enumeraci6n de 10s problemas que es precis0 gestionar en el cliente. En resumen, ADO.NET se adapta mejor a las configuraciones distribuidas, utilicen o no Internet como medio de comunicaci6n, a1 tiempo que ofrece una alternativa a1 us0 de cursores en configuraciones cliente/ servidor.

--

~

___---

_~

-

_--

- --

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 conjunto 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 servidor, el proceso dure el menor tiempo posible. La existencia de estos lectores de datos hace posible la recuperaci6n de informaci6n 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 fila. 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 aplicaciones, desde las mas sencillas de tip0 monousuario hasta aquellas que deben operar con conexi6n esporadica a1 servidor. Esto demuestra la flexibilidad y versatilidad de ADO.NET respecto a otros mecanismos de acceso a datos, mucho mas limitados en cuanto a posibilidades se refiere. Las distintas combinaciones de componentes ADO.NET, proveedores y controladores dan como resultado diferentes soluciones que pueden aplicarse a multiples escenarios, entre 10s cuales se encontrarian las siguientes configuraciones: 0

Monousuario: Aplicaciones con necesidades bisicas de tratamiento de datos, almacenamiento local de la informacidn, en la misma miquina, y que no precisan la consolidaci6n con un servidor. Es el modelo representado esquemtiticamente en la figura 4.2, en la que el recuadro representaria a1 ordena-

Prograrnacidn de bases de datos con V i s u a l Basic .NET

dor del cliente y 10s elementos que hay en su interior 10s diversos componentes. 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 primera 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

Ordenador del cliente (configuracion monousuario) Figura 4.2. Representacion esquematica de una configuracion monousuario

Los conjuntos de datos o DataSet pueden guardarse y recuperarse localmente con una llamada a un metodo, siendo la alternativa mas simple y rapida para el tratamiento de datos en aplicaciones sencillas. 0

Cliente/Servidor: La configuracih m6s utilizada en la Gltima decada del pasado siglo, separando la interfaz de usuario y logica de aplicacih, que se ejecutarian en el ordenador del cliente conjuntamente con ADO.NET, del almacenamiento de datos, que queda en manos de un servidor. En esta disposici6n aparecen en escena, como se aprecia en la figura 4.3, varios elementos mas, como el adaptador y el proveedor de datos y / o controlador, segun 10s casos. El adaptador de datos se comunica con el proveedor y hace posible la independencia de 10s conjuntos de datos, a1 separar su representach de la

4. lntroduccion a ADO.NET

que utiliza el origen de datos nativo. A pesar de que en esta configuracion, tipica de las redes internas de las empresas, seria posible una conexion continua con el servidor de datos, ADO.NET utiliza el mecanismo antes explicad0 de ejecucion de comandos y creacion de conjuntos de datos locales en el cliente, reduciendo la carga del RDBMS.

a,

1

0

1

Y

\

Configuracion cliente/servidor Figura 4.3. Esquerna de una configuracion cliente/servidor tipica 0

Cliente / Servidor con conexi6n espor6dica: Similar a la anterior, se caracteriza porque el cliente en ocasiones tiene la necesidad de trabajar con 10s datos sin contar con una conexion con el servidor, precisando una consolidation

Programacidn de bases de datos con Visual Basic .NET

posterior, cuando la conexi6n es posible. Eso es lo que ocurre, por ejemplo, cuando se trabaja con un ordenador portfitil durante un viaje, por ejemplo tomando pedidos de clientes que despu6s es necesario transferir a la base de datos para su proceso. La configuraci6n seria la de la figura 4.4. La aplicaci6n cliente se sirve de un conjunto de datos que almacena localmente, en formato XML, en el mismo ordenador. Cuando la conexi6n con el servidor estA disponible, se usan 10s mismos elementos cliente / servidor indicados antes para ejecutar 10s comandos de actualizaci6n apropiados.

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

0

Distribuida: Cuando las empresas tienen un cierto tamafio, el mantenimiento de aplicaciones que siguen el modelo cliente / servidor se convierte en un problema, ya que la actualizaci6n de 10s algoritmos de proceso de la informaci6n se encuentran codificados en la aplicaci6n que ejecuta cada ordenador cliente, lo cual implica que cualquier cambio conlleve una actualizaci6n a1 nivel de toda la empresa. Las aplicaciones distribuidas solucionan este problema, a1 aislar la 16gica de proceso de datos en un servidor de aplicaciones que actua como intermediario entre clientes y RDBMS. Es el modelo representado en la figura 4.5. En el aparecen en el servidor de aplicaciones 10s componentes ADO.NET necesarios para comunicarse con el RDBMS y efectuar todas las operaciones de manipulaci6n de datos. La informaci6n se transfiere a y desde el cliente, convertido en una simple interfaz de usuario, usando el formato XML. En este caso se habla de un modelo en tres capas o three-tier, por ser el m i s habitual, per0 es posible afiadir capas adicionales segun las necesidades de la empresa.

Los componentes que se ejecutan en el servidor de aplicaciones pueden ser componentes .NET o bien servicios Web. Estos cuentan con algunas ventajas, al ser mas facilmente accesibles a traves de redes en las cuales existen cortafuegos. 0

Web: En realidad es una variante del modelo anterior. Bisicamente se sustituye en el cliente la aplicaci6n nativa, basada en formularios Windows, por una aplicaci6n tip0 ASP.NET, obteniendose un cliente Zigero ejecutable en cualquier navegador. Los elementos ADO.NET asi como su distribuci6n serian idhticos.

Como puede ver, ADO.NET solventari nuestras necesidades en todos 10s casos, empleando siempre 10s mismos elementos bisicos: proveedores ADO.NET, controladores en caso de ser necesarios, adaptadores y conjuntos de datos.

Mientras desarrollamos una aplicaci6n de acceso a datos con Visual Studio .NET, comprobando su funcionamiento en una miquina de desarrollo, nunca tendremos problemas con 10s componentes porque a1 instalar Visual Studio .NET se instalan tambien automiticamente 10s MDAC, concretamente la versi6n 2.6. Hay que tener en cuenta, sin embargo, que las aplicaciones, a1 finalizar la fase de desarrollo y depuracibn, van a instalarse en miquinas clientes en las que, lbgicamente, no existiri Visual Studio .NET.

Programacidn de bases de datos con Visual Basic .NET

Configuracion distribuida Figura 4.5. Configuracion de una aplicacion distribuida en tres capas

En cualquier ordenador donde vayan a utilizarse 10s servicios de ADO.NET, ya sea un cliente, en 10s esquemas de las figuras 4.2 y 4.3, o bien 10s componentes de un servidor de aplicaciones, en la figura 4.5, debe instalarse la versi6n 2.6 o posterior de 10s componentes MDAC, para lo cual existe un archivo redistribuible que,

4. Introduccidn a ADO.NET

incluso, es posible combinar con la instalacion de nuestra propia aplicacidn, de tal forma que el usuario no tenga que preocuparse de obtener e instalar dichos componentes. Otro factor que hay que tener en cuenta son las referencias a servidores y caminos de archivos. Durante la fase de desarrollo habitualmente se utilizarin servidores de datos de pruebas, no aquellos que estin dando servicio a las aplicaciones en explotaci6n. Lbgicamente, a1 instalar la aplicaci6n debe pasar a utilizarse, precisamente, ese servidor de explotaci6n. En lugar de introducir directamente las referencias en el c6digo o 10s componentes, siempre existe la posibilidad de recuperar esa informaci6n de un archivo de configuraci6n, facilitando asi el cambio de un servidor a otro sin necesidad de tocar la aplicacibn, simplemente editando un archivo de texto.

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 previo, 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 referencia 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 informaci6n de referencia de Visual Studio .NET.

El modelo de objetos ADO.NET est6 construido de forma coherente y facilitando la posterior extensibn, gracias a la herencia y la implementaci6n de interfaces. Sus elementos podrian clasificarse en dos categorias: dependientes e independientes del origen de datos. En la primera entrarian todas las clases especificas para cada origen de datos concreto, como pueden ser OleDbDataAdapter y SqlDataAdapter para OLE DB y SQL Server, respectivamente. La segunda se compone de

5. Modelo de objetos

clases que no tienen dependencias respecto a1 origen de datos, como DataSet o DataRelation.

Los elementos independientes del origen de datos son de us0 general, independientemente de que conectemos con SQL Server, Oracle, dBase, Excel o un archivo XML. El mayor exponente es la clase DataSet, que representa un conjunto de datos en una aplicaci6n sin importar de d6nde se haya extraido. Las operaciones disponibles son siempre las mismas, lo cual nos facilitarB el trabajo a1 no tener que recurrir a distintos caminos segun el origen de datos empleado. Aquellos componentes que necesitan comunicarse con el origen de datos, y entender 10s comandos, funciones y estructuras de este, implementan interfaces comunes a pesar de sus diferencias. Asi, es posible tratar de manera homogenea un adaptador de datos de SQL Server o de Oracle, por poner un ejemplo, ya que cuentan con similares mktodos y propiedades aunque la implementacibn, como es 16gico, difiere de un componente a otro. Dada la independencia del origen de datos, las clases de us0 generico, como la citada DataSet, no necesitan ser extendidas para usos especificos. El conjunto de datos siempre serd el mismo, sin importar el origen de datos del que se haya obtenido o a1 que se vaya a enviar. Las clases con dependencias, por el contrario, tienen una estructura que permite una ampliaci6n fbcil. Esto ha facilitado, por ejemplo, que Microsoft aiiada ripidamente proveedores de datos especificos para ODBC y Oracle a 10s ofrecidos inicialmente con Visual Studio .NET para SQL Server y OLE DB. De igual manera, terceros fabricantes, e incluso nosotros mismos, podemos crear proveedores especificos para nuestros origenes de datos.

La instalaci6n por defect0 de la plataforma .NET aporta cinco Bmbitos con nombre o namespaces relacionados con ADO.NET, a 10s cuales habria que aiiadir uno o mBs por cada proveedor adicional que pudieramos instalar despues. Estos cinco Bmbitos son:

s ys tem. Data: Aloja las clases independientes del origen de datos, asi como las interfaces que deben implementar las clases que son dependientes. 0

System. Data. Common: Contiene clases que facilitan la implementaci6n de las interfaces existentes en System. Data por parte de 10s distintos proveedores de datos, asi como otras compartidas por todos 10s proveedores. System. Data.OleDb: Corresponde a1 proveedor ADO.NET que permite utilizar cualquier controlador OLE DB para conectar con un origen de datos. En 61 se encuentran implementaciones especificas de clases para comunicarse mediante OLE DB.

0

System.Data. SqlClient: Como el anterior, alberga clases especificas para operar sobre un determinado origen de datos, en este caso SQL Server.

Prograrnacidn de bases de datos con Visual Basic .NET

System. Data. SqlTypes: Relacionado con el anterior, en este 6mbito encontramos definiciones de tipos de datos especificos para trabajar con SQL Server.

Instalando 10s dos proveedores adicionales que Microsoft ha publicado hasta el momento para ADO.NET, a 10s anteriores habria que sumar 10s dos 6mbitos siguientes: System. Data.Oracleclient: Correspondiente a1 proveedor nativo para acceso a bases de datos Oracle. A1 igual que System. Data. Sqlcliente o Sys tem. Data .OleDb, contiene implementaciones especificas de clases que facilitan la conexi6n y comunicaci6n con este RDBMS. Microsoft. Data.Odbc: Este dmbito corresponde a1 proveedor ODBC nativo de ADO.NET, conteniendo 10s elementos que son necesarios para poder

acceder a cualquier origen de datos para el que haya disponible un controlador OLE DB.

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 datos 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 proveedores que no conoce de antemano. Esto es posible gracias a la existencia de unas interfaces genericas, predefinidas en el Ambito system. Data, que todo proveedor 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 emplean el prefijo I Db. Como se ver6 en 10s puntos siguientes, las del segundo grupo suelen estar derivadas 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

_

_

~

_

_

A1 crear un conjunto de datos local, en el ordenador en el que se ejecuta la aplicaci6n cliente, es preciso establecer una correspondencia entre las columnas del origen de datos y las existentes en dicho conjunto local. Esas dependencias se representan mediante la interfaz IColumnMapping, implementada en la clase ColumnMapp ing y todas las implementaciones especificas derivadas de ksta. IColumnMapping es una interfaz compuesta tan s610 de dos propiedades publicas: DataSetColumn y Sourcecolumn. La primera contiene el nombre de la colurnna en el DataSet,el conjunto de datos local, y la segunda el nombre que recibe en el origen de datos. Cualquier clase que implemente IColumnMapping estd obligada a implementar estas dos propiedades. Para facilitar dicha operacidn, en el Bmbito System. Data. Common encontramos la clase DataColumnMapping, que se limita a implementar las dos propiedades y ofrecer un constructor. Cualquier proveedor puede utilizar esta clase como base para crear las suyas propias en caso de que fuese necesario, si bien una asociaci6n entre columnas de origen y locales no requiere un trabajo adicional. Dado que un conjunto de datos suele estar formado por multiples columnas, por 16gica tienen que existir varios DataColumnMapping. La interfaz IColumnMappingColl e ction, implementada en la clase Da taColumnMapping Co 11e ction, actua como colecci6n de enlaces entre columnas origen y locales. En la figura 5.1 puede ver la relaci6n existente entre las interfaces y clases indicadas, asi como sus miembros mds destacables, en este caso las propiedades DataSetColumny SourceColumn. Las columnas no existen en un DataSet de manera aislada, sin0 que se agrupan en tablas representadas por objetos DataTable. Es preciso, por lo tanto, establecer tambien una correspondencia entre las tablas del origen de datos y las que existir6n en el DataSet, tarea de la que se encarga la interfaz ITableMapping. Esta cuenta tan s610 con tres propiedades: 0

SourceTable: Referencia a la tabla del origen de datos. DataSetTable: Referencia a la tabla que le corresponde en el DataSet.

0

ColumnMappings: Colecci6n con las asociaciones de columnas de esta tabla.

En el ambito Sys tern. Data. Common existe una implementaci6n de la interfaz ITableMapping en la clase DataTableMapping. De manera andloga a lo que ocurre con las columnas, tambikn existe una interfaz ITableMappingCollection con su correspondiente implementaci6n en DataTabl eCol1 e ction.

Los origenes de datos de tip0 RDBMS son capaces de facilitar un cursor, un motor software que el cliente puede utilizar, en el caso de ADO.NET, para acceder a

l

Programacidn de bases de datos con V i s u a l Basic .NET

filas de datos de manera unidireccional y con el unico prop6sito de leer datos, nunca de modificarlos. Cada proveedor facilitara una clase cuyo objetivo es facilitar la comunicaci6n con el cursor del servidor, clase que se conoce habitualmente como Reader o bien lector de datos. Dichas clases deben implementar las interfaces I Data Record e I Data Reader.

System.Data IColurnnMapping

IColurnnMappinqCollection

ColumnMapping

ColumnMappingCollection

DataSetColumn

SourceColumn

System.Data.Common

Arnbito con nornbre

Figura 5.1. Elementos relacionados con la asociacion de columnas entre conjuntos de datos locales y origenes de datos

La interfaz I Da t a R e c o r d define las propiedades y metodos necesarios para acceder a 10s datos alojados en las columnas de una fila de datos. Podemos saber el numero de columnas existentes mediante la propiedad Fie l d C o u n t , accediendo individualmente a cada una de ellas con la propiedad I tern. Esta interfaz cuenta, asimismo, con mas de una veintena de metodos del tipo G e t B o o l e a n ( ), G e t B y t e ( ) , G e t F l o a t ( ) y G e t S t r i n g ( ) , cuyo objetivo es recuperar el valor de una determinada columna en el formato especificado. Para poder operar sobre las columnas de una fila de datos, finalidad de I D a t a Record, antes es necesario recuperar esa fila, asi como tener la posibilidad de avanzar a la siguiente hasta llegar a1 final de las filas facilitadas. Este es el objetivo de 10s miembros de la interfaz I D a t a R e a d e r , entre 10s cuales estan 10s siguientes: 0

RecordsAf f e c t e d : Propiedad que contiene el numero de filas existentes.

0

Read ( ) : Metodo que lee la siguiente fila.

N e x t R e s u l t ( ) : Accede a1 siguiente conjunto de resultados en caso de exis-

tir varios. C l o s e ( ) : Cierra el lector.

Como ya sabe, las interfaces no pueden ser utilizadas directamente desde un programa propio para operar sobre 10s datos, siendo necesario emplear clases que las implementen. Estas dos interfaces se encuentran implementadas en las clases D a t a R e a d e r de cada proveedor, por ejemplo S q l D a t a R e a d e r , O l e D b D a t a R e a d e r , O r a c l e D a t a R e a d e r y O d b c D a t a R e a d e r . Cada una de ellas facilita una implementacih especifica de 10s miembros citados, afiadiendo a1 tiempo otros exclusivos en caso de ser necesario. S q l D a t a R e a d e r , por ejemplo, cuenta con una seriedem6todosGetSqlByte ( ) , GetSqlString(),GetSqlDouble(),etc.,que facilitan la recuperacih de columnas con tipos de datos exclusivos de SQL Server, mientras que el proveedor de Oracle dispone de m6todos tipo G e t O r a c l e B i n a r y ( ) , G e t O r a c l e N u m b e r ( ) y G e t O r a c l e S t r i n g ( ) , ajustados a 10s tipos de este RDBMS. La figura 5.2 representa la relaci6n entre 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 , definidas en el Eimbito S y s t e m . D a t a , y las clases D a t a R e a d e r de cada proveedor. Conociendo 10s miembros de las interfaces podremos trabajar con cualquier proveedor, sin tener que conocer su implementacih especifica.

Svstem.Data.SalClient

System.Data .OleDb

SqlDataReader

OleDbDataReader

System.Data IDa taRecord

Fieldcount Itern GetXXX ( )

IDa t a R e a d e r

Read ( ) NextResult ( ) 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

En el Octavo CapitUlO aprendera, en la practica, a usar laS ClaSeSDataReader de 10s proveedores para acceder a un origen de datos y recuperar inforrnacion.

Programacidn de bases de datos con Visual Basic .NET

Como se explic6 en el capitulo anterior, ADO.NET no emplea cursores de servidor para tratar la informaci6n si exceptuamos 10s cursores unidireccionales s610 de lectura representados por las clases DataReader.En su lugar, siempre que es precisa una navegaci6n mBs compleja o la edici6n de 10s datos, lo que se hace es ejecutar un comando y obtener un conjunto de datos local o DataSet. Para efectuar esa operation se necesita un adaptador de datos. Un adaptador de datos es el nexo de uni6n entre un origen de datos y un DataSet, el eslab6n que se encarga de adaptar la informaci6n de las dependencias propias del origen a1 caricter independiente del conjunto de datos local. Como seria de esperar, cada proveedor de datos cuenta con su propio adaptador especifico, si bien todos ellos implementan una interfaz comun: IDataAdap te r. Los miembros de la interfaz I Da taAdap te r tienen dos objetivos: recuperar filas del origen de datos convirtiendolas en filas del DataSet, por una parte, y generar 10s comandos necesarios para enviar las modificaciones del Data S et de vuelta a1 origen de datos. Entre sus propiedades y metodos m6s importantes estBn: 0

0

F i l l ( ) : Es el metodo encargado de recuperar filas del origen de datos incluyendolas en el Data S et local.

Update ( ) : Complementario a1 anterior, efectuaria las operaciones necesarias en el origen de datos para transferir las acciones de edici6n que haya sufrido el DataSet.

I Da taAdap te r es una interfaz gene'rica, aplicable tanto a origenes de tip0 RDBMS como a 10s que no lo son. Existe una interfaz derivada, IDbDa taAdap te r, especifica para 10s origenes que son bases de datos relacionales. I DbDataAdapter afiade a 10s miembros de su interfaz base cuatro propiedades: SelectCommand, Insertcommand, Updatecommand y Deletecommand, cuya finalidad es alojar las sentencias de seleccibn, insercibn, actualizaci6n y borrado de filas en SQL. La interfaz IDataAdap te r no es implementada directamente por clases especificas de 10s proveedores de datos, sino por las clases Da taAdap te r y DbDa ta Adapter que existen en el Bmbito System. Datacommon. De esta forma se ofrece una implementaci6n por defecto, gedrica, que despues cada proveedor hereda y puede personalizar segun precise. DataAdapter implementa la interfaz I Da taAdapter, mientras que DbDa taAdap te r es una clase derivada de Da taAdap te r y, por tanto, hereda la implementaci6n de IDataAdapter. Derivadas de DbDataAdapter,e implementando la interfaz IDbDataAdapter, encontramos una clase en cada proveedor: SqlDataAdapter, OleDbDataAdapter, OracleDataAdapter y OdbcDataAdapter. Estas clases cuentan con la implementaci6n por defecto de 10s metodos Fill y Update facilitada por DataAdapter y DbAdapter, a1 tiempo que ofrecen una implementaci6n especifica de las propiedades Select Command, Inse rtCommand, Upda teCommand y DeleteCommand que, presumiblemente, diferirBn de un proveedor a otro.

5. Modelo de objetos

En la figura 5.3 se ha representado la relaci6n existente entre las interfaces IDataAdapter e IDbDataAdapter respecto a las clases DataAdapter, DbDataAdapter y SqlDataAdapter,perteneciente a1 proveedor SqlClient.6sta podria ser sustituida por OleDbDataAdapter, OracleDbDataAdapter o bien OdbcDataAdapter sin cambiar m6s que el 6mbito de System. Data. SqlClient a1 que corresponda.

Svstem.Data I D b D a taAdapter

IDa taAdapter Fill ( ) Update ( )

SelectCommand Insertcommand Updatecommand Deletecommand

DataAdapter

DbDataAdapter

System.Data.Common

P

L

t

SqlDataAdapter

Svstem.Data.SalClient

~

Figura 5.3. La interfaz IDataAdapter es implementada por la dase DataAdapter, base de DbDataAdapter que, a su vez, es base de SqlDataAdapter. Esta ukima implementa la interfaz IDbDataAdapter

--

- . ~ _ _ _ _ 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 proveedor, per0 con el fin de facilitar, si es que desea, una codificaci6n independiente del

Prograrnacidn de bases de datos con Visual Basic .NET

proveedor, existen las interfaces IDbConnection, IDbCommand e IDbTransaction. Como puede suponer, la primera contiene 10s miembros relacionados con la conexi6n a la base de datos, la segunda tiene que ver con 10s comandos y la tercera con las transacciones. De la interfaz IDbConnection habria que destacar 10s miembros Connectionstring, Open ( ) , Close ( ) , Createcommand ( ) y BeginTransaction ( ) , que contiene la cadena de conexi6n a la base de datos, utiliza esa cadena para abrir la conexibn, cierra la conexidn, crea un nuevo comando asociado a esta conexi6n e inicia una transaccibn, respectivamente. En el punto anterior se indico que la interfaz IDbDataAdapter contaba con cuatro propiedades: S e 1e ct Command, InsertCommand, Upda t eCommand y Deletecommand. Todas ellas son referencias a la interfaz IDbCommand, en la que se definen 10s miembros que debe tener un comando que va a ejecutarse sobre una base de datos. Las propiedades CommandType y CommandText de la interfaz establecen el tip0 de comando y el texto, que puede ser el nombre de una tabla, una sentencia SQL, el nombre de una vista o procedimiento almacenado, etc., dependiendo del valor dado a CommandType. Un comando siempre se obtiene a partir de una conexi6n. La relaci6n entre esta y el comando la fija la propiedad Connection de IDbCommand, conteniendo una referencia de tip0 IDbConnection.Finalmente, IDbCommand cuenta con una serie de metodos cuya funci6n es ejecutar el comando, ya sea obteniendo un lector de datos o sin recuperar resultado alguno. Tambien las transacciones estan asociadas a una conexi6n de base de datos, por ello la interfaz IDbTransaction tiene una propiedad Connection, como IDbCommand. Por lo demAs, tan s610 hay tres miembros en esta interfaz: IsolationLevel, que determina el nivel de aislamiento de la transacci6n; Commit ( ) , que la confirma, y Rollback ( ) , que la descarta. Ninguna de estas tres interfaces cuenta con una implernentacion por defect0 en el dmbito System. Data. Common,a diferencia de la mayoria de las enunciadas en 10s puntos previos. Son 10s proveedores, directamente, 10s responsables de implementarlas. En cada uno de ellos debe existir una clase XXXConnection, una XXXCommand y una XXXTransaction, donde XXX seria el prefijo del proveedor: S q l , OleDb, Oracle u Odbc. La figura 5.4 resume algunos de 10s miembros de las tres interfaces, asi como las clases que las implementan en 10s Bmbitos de cada uno de 10s proveedores.

~-

S

Tras leer 10s puntos anteriores, ya se habra hecho una cierta idea sobre la composici6n de un proveedor de datos .NET y su funcionamiento. Cada proveedor se compone de una serie de clases que implementan determinadas interfaces definidas en System. Data, ya sea directamente, como ocurre con las tratadas en el

5. Modelo d e objetos

punto anterior a Gste, o indirectamente, a1 heredar la implementacih de las clases que encontramos en System. Data. Common.

Svstem.Data IDbConnec tion

Connectionstring open 0 Close ( ) Createcommand ( ) BeginTransaction ( )

II

bqlConnection OleDbConnection OracleConnecticn OdbcConnectior'

IDbCommand

CommandType CommandText ExecuteReader ( ) ExecuteNonQuery ( )

ID b T r - d n s a ct i o n IsolationLevel Commit ( ) Rollback ( ) J

hqlConunand

OleDbCommand Oraclecommand OdbcCornmand

(1) System.Data.SqlClient ( 3 ) System.Data.OracleC1ient

bq1,ransaction OleDbTransaction OracleTransaction OdbcTransaction

,

1

c I 1

(2) System.Data.OleDb ( 4 ) Microsoft.Data.0dbc

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.

Estas clases se denominan siempre Connection, Command, DataReader y Da taAdap te r, respectivamente, precedidas de la denominaci6n del proveedor: S ql en el de SQL Server, 01e Db en el de OLE DB, 0ra c1e en el proveedor de Oracle y Odbc en el proveedor para ODBC. Conociendo 10s miembros de las interfaces IDbConnection, IDbCommand, IDataReader e IDataAdapter, tratadas en 10s apartados previos, podremos usar las clases especificas de cualquier proveedor.

Aparte de las ya mencionadas, en el Bmbito s y s tern. Data. Common existen otras clases de us0 comun entre 10s proveedores. Todas ellas sirven como clases

Programacidn de bases de datos con Visual Basic .NET

base de otras, personalizadas para cada proveedor de datos concreto. Estas clases son DbDataPermission, DBDataPermissionAttribute, RowUpdatedEventArgs 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 SqlCommandBuilder, 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 informaci6n del origen de datos, para lo cual disponen de 10s mdtodos GetInsertCommand ( ) , 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 demas 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 producto de almacenamiento de datos.

CIases independientes del origen de datos Hasta ahora nos hemos centrado en el estudio de 10s elementos relacionados con 10s proveedores de datos ya que, a1 fin y a1 cabo, ellos son 10s que permiten a las aplicaciones acceder a la informacibn, recuperarla, editarla y volver a almacenarla. Una vez que esa informaci6n se encuentra en nuestra aplicacih, sin embargo, para operar sobre ella utilizaremos un conjunto de clases que son totalmente independientes del origen de datos. No existe, por ejemplo, una clase DataSet para SQL Server, otra para Oracle, una tercera para OLE DB y una mas para ODBC, sino que tenemos una unica clase Da taS et. De este conjunto de clases practicamente la unica que hemos mencionado ha sido DataSet, lo cual es 16gic0, ya que es posiblemente la mas importante de las eXiStenteS en System. Data.La clase DataSet es relativamente compleja, pUeSt0 que un conjunto de datos esti formado por una o mas tablas que, a su vez, se componen de columnas. Entre esas tablas, ademas, pueden existir relaciones, y cada una de las columnas puede tener activas ciertas restricciones. Cada uno de esos

5. Modelo de objetos

elementos, la columna, tabla, relaci6n o restriccion, se representa con una clase disponible en el 6mbito System. Data. Ya que estas clases son de us0 final, no tendremos que conocer despuks implementaciones especificas por proveedor, en 10s puntos siguientes se abordan con algo m6s de profundidad, a fin de que las conozcamos lo suficiente como para POder usarlas en 10s ejemplos de posteriores capitulos. Su us0 en la practica, no obstante, se dejar6 para m6s adelante.

Como se indica en la propia ayuda de Visual Studio .NET, el componente Data s e t es un elemento fundamental de ADO.NET, una clase en torno a la que existen muchas otras de las que depende. Un DataSet puede crearse mediante codigo 0, lo que resulta mucho m6s corriente, obtenerse a partir de un origen de datos mediante el correspondiente adaptador de datos. En el noveno capitulo conocer6 con detalle la forma de trabajar con la clase Data S e t y otras relacionadas con ella, por ahora nos limitaremos a mencionar sus miembros m6s relevantes. Estos son: DataSetName: Cada conjunto de datos cuenta con un nombre que le identifica, de igual forma que una tabla, vista o procedimiento almacenado tiene un identificador Linico. Este nombre normalmente se establece en el momento de la creacion del objeto DataSet, facilit6ndolo como par6metro a1 constructor, mientras que esta propiedad permite tanto obtenerlo como cambiarlo. 0

Tables: En el capitulo dedicado a SQL aprendi6 a componer sentencias SQL en las que se relacionaban varias tablas con el fin de obtener un conjunto de datos combinado. El conjunto de datos, por tanto, puede estar compuesto de varias tablas. La propiedad Tables es una referencia a una colecci6n DataTableCollection en la que se encuentran todas las tablas que forman el DataSet.

Mediante la propiedad Tables es posible acceder a las tablas de datos, cada una de las cuales esta representada por un objeto DataTable. Las operaciones se efectuan en las filas y columnas de cada tabla, afectando al conjunto de datos. 0

0

Relations: Si el conjunto de datos cuenta con varias tablas, entre ellas necesariamente existirAn relaciones. Esta propiedad es una referencia a un objet0 DataRelationCollection que aloja todas esas referencias. 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

cambios se almacenan provisionalmente separados de 10svalores del conjunto de datos original, permitiendose posteriormente su aceptaci6n o rechazo. Acceptchanges ( ) : Provoca una llamada en cascada a1 m6todo hom6nimo de cada una de las tablas referenciadas en la propiedad Tables que, a su vez, llaman a1 mismo metodo de cada una de las filas, propagando asi la aceptaci6n de todos 10s cambios que hubiese pendientes en el conjunto de datos. Re] ectchanges ( ) : Su funcionamiento es similar a1 del metodo anterior, per0 en este caso deshaciendo 10s cambios en lugar de aceptandolos. Writexml ( ) /ReadXml ( ) : Guardan y recuperan el conjunto de datos localmente en formato XML, ya sea en un archivo o flujo de datos previamente preparado. WriteXmlSchema ( ) /ReadXmlSchema ( ) : Sirnilares a 10s anteriores, per0 afectando tan s610 a1 esquema XML de 10s datos, no a 10s datos en si.

La mayoria de estos metodos cuentan con multiples versiones sobrecargadas. En la documentaci6n electronica de Visual Studio .NET encontrar5 10s detalles relativos a 10s parametros que acepta cada una de esas versiones y su comportamiento.

Un conjunto de datos o DataSet consta, basicamente, de tablas y relaciones. Cada una de las tablas, a las que se tiene acceso mediante la propiedad Tables segun acaba de verse, esta representada por un objeto de la clase DataTable. Esta cuenta con 10s miembros necesarios para poder acceder a las filas de datos, saber qu6 columnas componen cada fila, qu4 restricciones existen, etc. Tambi6n dispone de m6todos para aceptar y rechazar cambios, afiadir nuevas filas, recuperar aquellas que cumplen un cierto criterio, etc. Cada tabla se identifica con un nombre que se almacena en la propiedad TableName de la clase DataTable. La relaci6n entre una tabla y su conjunto de datos queda reflejada en la propiedad DataSet del DataTable. Algunas de las propiedades mas relevantes de DataTable son: 0

0

0

0

ROWS: Da acceso a la colecci6n de filas de datos que componen la tabla, representada cada una de ellas por un objeto de la clase DataRow.

Columns: Colecci6n de todas las columnas de la tabla. Cada columna se representa con un objeto de tipo Datacolumn. Constraints: Referencia a un objeto Constraintcollection que contiene todas las restricciones de esta tabla. PrimaryKey: Identifica la columna o columnas que actdan como clave primaria de la tabla.

5. Modelo de objetos

ChildRelations / ParentRelations: Cada una de ellas contiene una referencia a un objeto DataRelationCollection, en el primer caso con las relaciones hijo de la tabla y en el segundo con las relaciones padre. Esta informaci6n puede utilizarse para, por ejemplo, obtener todas las filas hija de una dada en una relaci6n maestro/ detalle entre dos tablas.

Mediante la propiedad Rows se tiene acceso a las filas de datos actuales, pudiendose modificar su contenido o eliminarse. Si queremos aiiadir filas se emplea el metodo NewRow ( ) del propio objeto DataTable. Los cambios efectuados pueden aceptarse, con Acceptchanges ( ) , o descartarse, llamando a Re] ectChanges ( ) . 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 habitual 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 actual 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 ejecutando automaticamente todas las comprobaciones y restricciones que haya definidas 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, ademas, dichos cambios tienen interdependencias que pudieran causar estados invalidos. De ser asi, antes de iniciar las modificaciones deberiamos llamar a1 metodo BeginEdit ( ) del DataRow, inhibiendo tanto las comprobaciones como la generaci6n 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 momento cuando se ejecuten todas las restricciones y produzcan 10s eventos. Tambi4n 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 errores, 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 multiples 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

0

Defaultvalue:Valor por defecto para la columna.

0

AllowDBNull: Indica si puede dejarse un valor nulo en la columna.

0

Unique: Determina si 10s valores de la columna deben ser unicos entre todas las filas de la tabla. AutoIncrement: Especifica si la columna contiene un valor que se incrementar5 autombticamente.

Como puede ver, 10s miembros de DataRow definen las caracteristicas a 10s que tendran que ajustarse 10s valores de una cierta columna. Dichos valores, no obstante, se almacenan en las filas, es decir, en objetos DataRow.

__

- _-

Una de las propiedades de DataTable,llamada Constraints,es la encargada 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 albergar5 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 tabla, 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 coleccion es exactamente igual que dar el valor True a la propiedad Unique del DataColumn que representa a la columna cuyos valores tienen que ser unicos. Las restricciones de clave externa, correspondientes a la clase ForeignKeyConstraint,son m5s complejas. A1 crearse relacionan una columna de una tabla con una columna de otra tabla, impidiendo la inconsistencia de sus valores. Adem5s, esta clase dispone de dos propiedades, UpdateRule y DeleteRule,que establece 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.

Las restricciones existentes en un conjunto de datos, y que se definen al nivel de cada tabla, no se comprueban a menos que la propiedad EnforceConstraints de la clase DataSet sea True,que es su Valor por defecto.

Segun se indicaba anteriormente, si en un DataSet existen multiples DataTable es precis0 definir la relaci6n que guardan entre ellos. Con este fin se utiliza la clase

Programacidn de bases de datos con V i s u a l Basic .NET

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 integridad 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 columnas que actuarian como clave externa. Estos valores tambikn pueden ser establecidos con las propiedades ParentTable, Parentcolumns, ChildTable y Chi IdColumns, respectivamente. A1 crear una relacion 6sta genera implicitamente dos restricciones que se aplican a las tablas participantes en dicha relacion. Por una parte, se aplica una restricci6n 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 porque no se sabria a quk fila de la tabla maestra corresponden las de la tabla de detalle. Por otra parte, tambien se crea una restriccion ForeignKeyConstraint aplicada a la columna de la tabla de detalle, impidiendo asi que se introduzcan valores 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, conteniendo 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 contiene la tabla del origen de datos a1 que estti asociado, ofreciendo una vista por defecto. 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 DataView o bien posteriormente, sirvikndose de las propiedades RowFil ter, RowStateFilter 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 ordenartin 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

Nada impide crear multiples objetos D a t a V i e w sobre el mismo D a t a T a b l obtenikndose diferentes vistas de 10s mismos datos segun el orden y criterios d selecci6n que interesen.

A1 finalizar la lectura de este capitulo posiblemente se sienta confundido abrumado, lo que no es extrafio teniendo en cuenta la cantidad de interfaces, cl ses, propiedades y mktodos que se han introducido de forma rdpida y exclusiv mente teorica. Esto no debe preocuparle. No se trata de que sepa qu6 clases ha en que dmbito se encuentra o qu6 miembros cuentan, ya que toda esa informaci6

Prograrnacidn de bases de datos con Visual Basic .NET

la puede encontrar rdpidamente en la referencia de la ayuda de Visual Studio .NET. El objetivo del capitulo era familiarizarle con todos 10s elementos mencionados, a fin de que le resulten familiares y tenga una idea aproximada de c u d es su funci6n y relaci6n con 10s demds. Este conocimiento, que ird afianzando a medida que siga leyendo, nos servird para, en capitulos siguientes, profundizar en el estudio de cada interfaz o clase en particular, ponikdolas ya en prdctica mediante el desarrollo de algunos ejemplos simples per0 demostrativos.

Los dos capitulos previos, fundarnentalmente tebricos, seguramente le habran resultado arduos de leer, per0 la teoria es necesaria, a1 menos en una cierta proporci6n, para poder abordar con un minimo de familiaridad el desarrollo de 10s proyectos que van a proponerse a partir de ahora, comenzando con este capitulo. Nuestro objetivo, en este sexto capitulo, es conocer todo lo necesario para poder conectar con distintos origenes de datos, poniendo ese conocimiento en practica a1 escribir pequeiios programas que abran y cierren dicha conexi6n. Aprender6 a usar las diferentes clases Connection, una por proveedor, y tambikn la sintaxis de las cadenas de conexi6n de ciertos proveedores, como 10s de OLE DB y ODBC.

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 menor rendimiento. Por ello, siempre que sea posible es preferible el us0 de proveedores de datos nativos y especificos para cada origen.

6 . Conexidn a1 origen de datos

Tras la presentacidn de Visual Studio .NET Microsoft ha liberado dos proveedores m6s: Oracleclient y Odbc,parar operar directamente sobre bases de datos Oracle y usar controladores ODBC, respectivamente. A continuaci6n se indica d6nde puede obtener estos controladores y c6mo instalarlos en su sistema.

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. Despliegue la secci6n del menu que aparece a la izquierda el apartado Downloads y seleccione 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 encontrari 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.

El proveedor de ADO.NET para Oracle ocupa 1,3 megabytes, mientras que el proveedor ODBC no llega al megabyte. El archivo de instalacion del primer0 es oracle-net .msi y el del segundo odbc-net .msi.

~~~~~

Microsoft facilita 10s proveedores de datos en archivos MSI autoinstalables, por lo que el proceso es realmente sencillo. Localice el archivo que contiene el proveedor, por ejemplo oracle net.msi, y haga doble clic sobre el. La instalacion se pondr6 en marcha, mostra%dose un asistente compuesto de varias piginas en las que, b6sicamente, puede limitarse a ir pulsando el b o t h Next > hasta llegar a1 ultimo paso (v6ase figura 6.2) donde hariamos clic sobre Install. Durante la instalaci6n se aiiadir6 a1 menos un nuevo ensamblado a1 GAC, conteniendo el c6digo del proveedor, asi como un nuevo grupo a la carpeta Programas con la documentaci6n exclusiva del proveedor instalado. A partir de este momento ya podemos usar el nuevo proveedor, algo que haremos en 10s puntos posteriores utilizando 10s dos indicados antes y que se asume que habri obtenido e instalado en su sistema.

Programacidn de bases de datos con Visual Basic .NET

F

F

Microsoft .NET Data Provider for Oracle 0 MSDN subscr,ber 0

~

The MrcroraftC NET Framework Data Provider for Oracle IS an add on S n e (bytes]: component to~ the Microsoft NET Frameworkthat provides accessd to an ~ ~ i ~ ~ ~ Last “Pdated: Oracle database using the Oracle Call Interface (OCI) as provided by Oracle Client software Oracle St Release 3 (8 1 7) Client or later must be supported:

~ %,

Wel~ometo Downloads

1

CDmpOnentDeYelopment

I3 Data Access and Databases

1,351 07J17J2002 NO

installed for this o r w i d e r to funaion &Download

NET Framework

0 0 0 0 0 0

NET show Terrarium and Adive Sewer Pages

NET Show LIVE’ From the

ODBC NET Data Provider NET Show

NET Dwr Win


c1

I-

+

/ >

&

-

+

Whlle Lector.Read0 Console.WriteLine (Lector("1SBN") End While

&

vbTab

&

Lector("Tltu1o") )

End Module

Observe cdmo se define el comando y, tras solicitar el c6digo de editorial por la consola, se aiiade un elemento a la coleccidn p a r a m e t e r s creando un nuevo O r acle P a r a m e t e r. El resultado de ejecutar el programa, uno de 10s posibles, seria el de la figura 8.6. Podria aiiadir, antes de solicitar el cddigo de editorial a1 usuario,

8. Recuperacio'n de datos

el c6digo necesario para mostrar el c6digo y nombre de cada una de ellas, facilitando asi la selecci6n.

Figura 8.6. Lista de 10s titulos pertenecientes a la editorial seleccionada

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 sentencia de consulta ser6 dnico, por ejemplo una suma, contador o algdn otro cdculo. 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 "WHERE Editorial=:CodEditorial"

"

L

-

A continuaci6n se solicita el c6digo de editorial a1 usuario e introduce como par6metro en el comando, que ahora ejecutaremos asi: Dim Resultado As Integer = Cornando.ExecuteScalar0 Console.WriteLine("Esa editorial tiene { O l titulos", Resultado)

Hemos eliminado la declaraci6n del DataReader y la llamada a1 metodo Close ( ) . Si ejecuta ahora el programa, e introduce el c6digo de una editorial, ver6 aparecer el ncmero de titulos que corresponden a ese c6digo.

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

comando preparado en un objeto Command puede contener cualquier tip0 de sentencia SQL, incluidas las que aiiaden filas, modifican las existentes o las eliminan. Este tip0 de sentencias no devuelve conjuntos de resultados, sino un entero que indica el numero de filas que se han visto afectadas por la operaci6n realizada. Por ello se ejecutan con el metodo ExecuteNonQuery ( ) en vez de ExecuteReader ( ) . Conociendo la sintaxis SQL del origen con el que vayamos a conectar, efectuar cualquier operaci6n de manipulaci6n de datos no implica mayor complejidad. El siguiente ejemplo aiiade una fila de datos a la hoja Libros del documento Excel. La operaci6n se efectuaria de manera anfiloga en cualquier otro origen y, de forma similar, podrian modificarse o eliminarse filas. Imports System.Data.OleDb Module Module1 Sub Main ( 1 rA

Dim Conexion As New OleDbConnection( "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 l b r o s . ~ l s ; "Extended Properties='Excel 8.0; HDR=Yes'") ~

Dim Cornando As OleDbCommand

Conexion.CreateCommand

&

( )

0

Cone 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

Conexion.Close i End Sub

'

'

?

I

.

=

)

Comando.ExecuteNonQuery()

I

/

,

End Module

Para ver el resultado puede ejecutar alguno de 10s ejemplos previos, recuperando el contenido del documento y mostrhdolo por la consola, o bien abrir directamente 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

Sin embargo, en ocasiones el origen de datos, en caso de ser un RDBMS, mantiene estructuras prefabricadas como las vistas y procedimientos almacenados, cuyo objetivo es facilitar nuestro trabajo a1 efectuar operaciones relativamente complejas, eximihdonos a nosotros de codificarlas en SQL. En las bases de datos que estamos empleando a mod0 de ejemplo, concretamente en las de SQL Server, Oracle e InterBase, introdujimos la definicidn de una vista y dos procedimientos almacenados. A continuacidn va a utilizarse el proveedor Sqlclient para operar con SQL Server, pero el procedimiento seria el mismo con cualquiera de 10s otros origenes, simplemente habria que cambiar de proveedor, poco mds.

Recuperacion de una vista Las vistas, una vez definidas en la base de datos, no se diferencian demasiado, en cuanto a tratamiento, respecto a las tablas. Podemos consultarlas con una sentencia SQL corriente, seleccionando 10s datos que nos interesen. Dependiendo de la vista y del RDBMS, posiblemente tambien pueda utilizarse para manipular la informacidn. En nuestra base de datos SQL Server tenemos definida una vista, llamada Libros Edi torial, que devuelve una lista de las editoriales existente junto con 10s titulos que le corresponden a cada una, ordenando la lista alfabeticamente por el nombre de la editorial. Para recuperar esta vista, ejecutando la sentencia SQL y obteniendo su resultado, crearemos una nueva aplicacidn de consola con el cddigo siguiente: Imports System. Data.SqlClient 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

-

3

2

-

3

-

D i m Comando As SqlCommand

Conexion. Open (

)

'

j




Dim VistaEditoriall A s N e w DataView(Datos.Tables("Libros"), " Ed i to r i a 1= 1 " , " Pr e ci o DESC" , DataViewRowState.CurrentRowsi ~

I

'

*

-

1

I

1

Muestra Fi las "Todas las filas", VistaTotal) Mues t ra Fi las "Libros d e programacion", VistaProgramacion) MuestraFilas "Titulos de la editorial l", VistaEditoriall) End Sub

Hemos optado por establecer 10s criterios de selecci6n y ordenaci6n en el mismo momento en que se crea cada Dataview, facilitando 10s m6todos apropiados a1 constructor de dicha clase. A1 final tenemos tres objetos que ofrecen vistas diferentes de la misma tabla de datos. Para trabajar con estos objetos tendremos, asimismo, que hacer algunos cambios en el m6todo Mues t ra Fi1as ( ) . Este quedaria como se muestra a continuacih: ,c

su

trin

Ti

Console.WriteLine(Titulo

&

vbCrLf

&

Vista

As Dataview)

New S t r i n g ( " - " , 7 0 ))

D i m Fila As DataRowView

For Each Fila In Vista { 1,6) {2,3) Console. WriteLine ( " { 0,-50 } Fila("Titulo"), Fila("Precio"), Fila("Editoria1") ) Next ' I ,

f

,

J

i

i

Console.WriteLine (vbCrLf C o n s o l e . Readi 1 ne ( ) End Sub

&

"Pulse para continuar")

Observe que la variable Fila ahora no es un DataRow sino un DataRowView. Asimismo, el elemento que se recorre en el bucle For Each es la propia vista entregada como segundo argumento, no un arreglo de objetos DataRow. El resultado, tal y como se aprecia en la figura 10.3, es casi id6ntico a1 del ejemplo previo, exceptuando el orden de 10s datos en la segunda y tercera vista.

Cada DataTable cuenta con una vista por defecto, un objeto DataView a1 que hace referencia la propiedad Def aultview. Esta vista, inicialmente, hace referencia 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

La configuracion del D e f a u l t v i e w afecta a las filas devueltas por la vista, per0 nunca a las contenidas en la propiedad Rows del D a t a T a b l e que siempre sera la coleccion de todas las filas que haya en la tabla.

En lugar de crear mLiltiples vistas diferentes, lo cual en ocasiones puede no ser imprescindible, podemos modificar las propiedades de D e f a u l t V i e w segLin las necesidades de cada caso. Es lo que se hace en la siguiente versi6n modificada del mismo ejemplo anterior. El metodo Mues t r a F i l a s ( ) se mantiene identico a1 punto anterior. Sub Main( j

__

I :, , - ...~ L i ~ i . i i . L.A,2 ~ . : c : ~ c . ~ i ~ ~ ~ : Dim Conexion As New SqlConnection( "Data Source=inspiron; Initial Catalog=Libros; "User ID=sa; Password=") ~

i.

il,,~

"

&

-

Prograrnacidn de bases de datos con Visual Basic .NET

Dim AdaptadorLibros As New SyiDataAdapter( "SELECT * FROM Libros", Conexion) r

r

Dim Datos As New DataSet ("MisDatos") Adapt adorLibros . Fi 11 ( Da tos, "Lib r o s " I

r

L

-

--

1

i

L - L t

~

Dim MiTabla As DataTable

=

i

i

)

_,

Datos.Tables("Libros") L -

MuestraFi1asi"Todas las filas", MiTabla.DefaultView)

MiTabla.DefaultView.RowFi1ter = "Titulo LIKE ' Proqramacion* "'

~

MuestraFiias("Libros d e prograrnacihr,", MiTabla.DefaultView)

Wi

. RowFilter

=

"Editorial=l"

. S o r t = "Precio DESC"

.RowStateFilter End With

=

'

DataViewRowState.Currer1tRows

1

MuestraFilas("Titu1os d e la editorial l", MiTabla.DefaultView) End Sub

El resultado, a1 ejecutar este ejemplo, seria identico a1 mostrado en la figura 10.3, exceptuando el orden alfab6tico de las filas en la segunda vista.

Bhsqueda de datos en una vista Una vista facilita un subconjunto de las filas de una tabla, sobre la base de un filtro de seleccih, en un determinado orden. Este viene determinado por el valor de una o m i s columnas que, en cierta manera, actdan como columnas clave en esa vista, facilitando operaciones rApidas de bdsqueda. En la clase DataView existen dos mdtodos, Find ( ) y FindRows ( ) , cuya finalidad es encontrar la primera fila o el conjunto de filas, respectivamente, que tienen un cierto valor en esa columna clave. El primero devuelve un entero que es el indice de la fila dentro del Dataview, mientras que el segundo facilita un arreglo de objetos DataRowView con todas las filas que lo contienen. Puede efectuar una pequeiia prueba iniciando una nueva aplicaci6n de consola e introduciendo el c6digo siguiente:

10. Relaciones y vistas

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

Cons o 1e .W r i t e L i n e ( " * * * Co 1urnn a s d i s po n I b 1e s * * * " 1 For Each Columna In M i T a b l a . C o l u m n s C o n s o l e . W r i t e L i n e (vbTab & " - " & Columrla. ColurnnNarne) Next

C o n s o l e . W r i t e ( " I n t r o ~ u z ~ea l nc mbrc de l a "columna F o r l a q u e q u i e r e o r d e n a r : " ) NombreColumna = Console.ReadLirle ( )

MiTabla.DefaultView.S3rt

=

"

&

NombreCclumna

M u e s t r a F i l a s ("Todas las filas", M i T a b l a . D e f a u l t v i e w ) .

?

Corlsole.Write ( " I n t r o d u a c a e l v a l o r a buscar: ValorBuscado = C o n s o l e . R e a d L i n e ( ) D i m I n d i c e As Integer = M i T a b l a If I n d i c e -1 Then Console.W r i t e L i r i e ( " { 0,- 5 0 1 { MiTabla.DefaultView(Indice) MiTabla. D e f a u l t v i e w ( I n d i c e ) MiTabla. D e f a u l t V i e w ( 1 n d i c e )

End If End Sub

")

Def a u l tView . F i n d ( ValorBuscado ) r 3 1

{2,61",

"Titulo"), "Editorial"), "Precio") 1

-

Pvogramacidn de bases de dafos con Visual Basic .NET

Sub MuestraFllas(ByVa1 Titulo A s String, ByVal Vista As Dataview)

Console.WriteLine(Titulo Dim F i l a As DataRowView

&

vbCrLf

&

New String("-", 7 0 ))

Fo

Conso 1e .Wr 1 t eLi ne ( " { 0,13 I { 2,- 3 0 1 i 1,-50 l I 3I 6 1 Flla("ISBN"), Fila("Titulo"), Fila("Autor"), F i l a ("Precio"), Fila ("Editorial")) Next

i4,31

" I

End Sub End Module

Usamos una vez mAs la tabla L i b r o s de Sc Server, aunque podriamos utilizar cualquier otro origen de datos. Tras crear el adaptador de datos y generar el D a t a S e t , enumeramos las columnas de la tabla para que, a traves de la consola, el usuario del programa pueda seleccionar una de ellas para ordenar las filas. Asignamos el nombre de columna introducido a la propiedad S o r t del DataView y, act0 seguido, mostramos el contenido de la vista. AparecerAn, como puede verse en la figura 10.4, las filas ordenadas por esa columna. A continuaci6n solicitamos un valor a buscar, mostrando algunos datos de la primera fila que lo contenga en la columna clave. Puede modificar esta parte final para, en h g a r de llamar a F i n d ( ) , emplear el metodo FindRows ( ) y enumerar todas las filas que coinciden.

Figura 10.4. Seleccionamos el orden de las filas y un valor a buscar

10. Relaciones y vistas

En este ejemplo no se han controlado las posibles excepciones que podrian generarse, por ejemplo al introducir el nombre de una columna inexistente para ordenar por ella.

Edicion de datos en la vista Una vista de datos, siempre que contenga informaci6n suficiente como para asociar cada fila de la vista con la fila original en la tabla, puede utilizarse tambidn para actualizar datos, modificando el contenido de las filas, afiadiendo otras nuevas o bien eliminando las existentes. El procesol en todos 10s casos, es igualmente sencillo:

Editar una fila existente: Localizado el objeto DataRowView que corresponda, llamariamos a1 metodo BeginEdit ( ) para iniciar 10s cambios, tras lo cual modificariamos el valor de las columnas que deseemos. El proceso terminaria con una llamada a EndEdit ( ) , para confirmar 10s cambios, o bien CancelEdit ( para deshacerlos. 0

Aiiadir una nueva fila: Invocamos a1 metodo AddNew ( ) del DataView para asi obtener un nuevo DataRowView,asignando a continuaci6n 10s valores de todas sus columnas y, como en el caso anterior, confirmando 10s cambios o descartindolos mediante 10s metodos EndEdit ( ) y CancelEdit ( ) . Eliminar una fila: Basta con llamar a1 metodo Delete ( ) del DataRowView a eliminar. En realidad la fila no se elimina en ese instante, sino que se modifica su estado para que aparezca como candidata a ser eliminada.

Cualquier modificaci6n de las filas causari que en el DataTable del que depende 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 AcceptChanged ( ) 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

Dim Conexion As New SqlConnectlon( "Data Source=inspiron; Initial Catalog=Llbros; "User ID=sa; Password=" ) 7

. t z * + 4 ,

1

iP

# ?

, >

Dim AdaptadorLibros As New SqlDataAdapter( "SELECT * FROM Libros", Conexion)

-

"

&

-

Programacidn de bases de datos con Visual Basic .NET

I

Dim Comandos As New SqlCommandBuilder(AdaptadorL1bros) I c Dim Datos As New DataSet ("MisDatos") +

Dim Vista As New DataView(Datos.Tables("Libros"), "Editorial=l", "ISBN ASC", DataViewRowState. CurrentRows ) 2

.

i

MuestraFilas ("Filas iniciales", Vista) Console.WriteLine(vbCrLf

, -,:'+

1

Dim Fila As DataRowView

"Se afiade una nueva fila"

& r::

=

&

vbCrLf)

_ %

Vista.AddNew()

Fi 1a ( " ISBN" ) = " 8 4 - 4 1 5 - 1 4 0 2-X" Fila ("Titulo"j = "Guia prdctica ASP.NET" Fila ("Autor") = "6scar Gonzdlez" Fila ("Editorial") = "1" Fila("Precio") = 10.75 Fila.EndEdit (

)

'

MuestraFilas ("Tras aAadir la nueva fila", Vista)

AdaptadorLibros.Update(Datos.Tables("Libros") End Sub

Ademris del conjunto de datos y el adaptador, ahora creamos tambien un CommandBuilder que se encarga de generar las sentencias de actualizacibn, inserci6n y borrado del origen de datos. Act0 seguido creamos una vista y mostramos las filas que la componen, tras lo cual aiiadimos una nueva fila y confirmamos 10s cambios, tanto en el DataRowView,con la llamada a EndEdit ( ) , como en el propio origen de datos, llamando a Update ( ) . Si todo va bien, la ejecuci6n de este programa deberia generar el resultado que puede verse en la figura 10.5. Tras ejecutarlo, puede comprobar el contenido de la tabla L i b r o s , por ejemplo desde el Administrador corporativo de SQL Server, para ver la nueva fila insertada. Como en casos anteriores, y por mantener la simplicidad del cbdigo, no se han controlado las posibles excepciones de ejecuci6n que podrian generarse. Aunque en este ejemplo tan s610 se inserta una fila, igualmente podrian haberse modificado datos de las existentes o haberlas eliminado. El proceso es exactamente el mismo, cambiando s610 la llamada a AddNew ( ) por la acci6n que corresponda.

10. Relaciones y vistas

Figura 10.5. La vista de datos antes y despues de aiiadir una nueva fila

La clase DataRowView dispone de dos propiedades, IsEdit e IsNew,que nos permiten saber si la fila esta en mod0 de edicion o si se trata de una nueva fila, respectivamente.

Utilizando las propiedades de Da t aVi ew, conjuntamente con m6todos de DataTable como GetChildRows ( ) , desde c6digo no necesitamos m6s para gestionar relaciones maestro/detalle entre dos o m6s tablas. El caso, sin embargo, es totalmente distinto cuando van a utilizarse componentes de interfaz que es necesario vincular con origenes de datos. Es en este context0 en el que encuentra su mayor utilidad la clase DataViewManager. Suponga que quiere mostrar en una cuadricula, en el interior de un formulario Windows, una serie de editoriales como filas primarias y ciertos titulos de cada una de ellas como filas secundarias. Tras crear una nueva aplicacidn Windows e insertar en el formulario, como Lhico componente, un DataGrid, aiiadimos el c6digo siguiente a1 evento Load: I

i,! .-c iJ

: ,:iii.i '- ", ., uI2-i L j~ -

L : . : ~ . q ~ 511 ~ ~ L:,:~~:;c?.5 ~

Dim Conexion As New SqlConnection( "Data Source=inspiron; Initial Catalog=Libros; "User ID=sa; Password=")

"

&

-

Programacidn de bases de datos con Visual Basic .NET

D i m AdaptadorEditoriales As New SqlDataAdapteri -

"SELECT * FROM Editoriales", Conexion) D i m AdaptadorLibros As New SqlDataAdapter( "SELECT * FROM Libros", C o n e x i o n ) .t-

D i m Datos As New DataSet ("MisDatos") 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

=

Adapt 11 (Datos, "Editoriales") AdaptadorLibros. F i l l (Datos, "Libros")

, Dato?.Relations.Add(New DataRelation ("Libros d e l a editorial", Datos.Tables ("Editoriales"). C o l u m n s ("IDEditorial"), Datos.Tables ("Libros"). C o l u m n s ("Editorial")) ) ~

DataGridl. Datasource Data Gr i d 1 . Da t aMembe r

= =

Datos " Edit or i a 1es "

A1 ejecutar el programa, la cuadricula mostrari un aspect0 similar a1 de la figura 10.6. A1 pulsar en el nombre de la relacidn, la editorial seleccionada se indicarg en la parte superior de la cuadricula y aparecerin 10s datos de todos sus titulos.

No se preocupe en este momento por las particularidades del componente DataGrid 0 laS propiedades de vinculacion DataSource y DataMember,!as estudiaremos en un capitulo posterior. En este ejemplo las usamos simplemente para mostrar la funcionalidad de la clase DataViewManager. Suponga que quiere permitir a1 usuario la introduccidn de parte de un titulo, de tal forma que las editoriales sdlo muestren 10s libros cuyo titulo comience por el texto dado. En principio, podriamos intentar hacer lo siguiente: Datos . Tab1 es ( "Libros" ) . De f aultVi ew. RowFi 1ter "Titulo LIKE ' Programaci6n* "'

=

-

Con esto, las editoriales tan sdlo deberian mostrar 10s libros cuyo titulo comenzase con 10s caracteres P rog rama cion A1 ejecutar el programa, sin embargo, veri que el resultado es exactamente el mismo que obtenia antes. Con la sentencia I'

10. Relaciones y vistas

anterior estamos modificando el filtro de la vista por defecto de la tabla Libros, per0 lo que estamos mostrando en el DataGrid es el DataSet completo, no una vista en particular, asi que intentamos lo siguiente: DataGrid1.DataSource

=

Datos.Tables("Editoriales"].DefaultView

-.__-_______-.__ ~

ultimedia

Telemaco. 43 EdificioValreaiW,l'phnta 901 Grsiscn Street 605 Thtrd Avenue New Ywk

Figura 10.6. Lista de editoriales en la cuadricula

Vinculamos el DataGrid con la vista por defecto de la tabla Editoriales, ya que queremos tener la posibilidad de seleccionar 10s titulos de cada editorial por separado, per0 el filtro asignado a la vista por defecto de la tabla Libros sigue sin aplicarse. Es en estos casos donde resulta util la clase DataViewManager, ya que puede enlazarse directamente con el DataGrid facilit6ndole todos 10s parametros de las vistas individuales de cada una de las tablas relacionadas. Sustituya las dos sentencias anteriores por el c6digo siguiente: Dim ViewManager As New DataViewManager(Datos) ViewManager. DataViewSettings ( " L i b r o s " ) .RowFilter "Titulo L I K E ' Prograrnaci6nt "' DataGridl. Datasource Da t a G r id 1 . Da t aM e rnb e r

= =

= -

ViewManager " Ed i to r i a 1e s "

Creamos un nuevo DataViewManager asocihdolo con el DataSet. A continuaci6n usamos la colecci6n DataViewSettings para establecer el filtro de la selecci6n sobre la tabla Libros. Por ultimo, enlazamos el DataViewManager directamente con el DataGrid. Ahora, al ejecutar el programa, podrti seguir seleccionando cada editorial por separado, per0 s610 aparecer6n 10s libros cuyo titulo comience por el prefijo indicado, como se aprecia en la figura 10.7.

Prograrnacidn de bases de datos con Visual Basic .NET

b

c

6

ie

W i15-1392 ?A 415-13'5N 4151351 54-4151261

ProgmmaclonconMs~alCP N E I Prcgranucioncon\,isual Stvdio N E T Prcgramaaonoon\Asual Basic NET Prcqramanoncon k l p k i 6 ) Kylix

FraroscoCb FranciscoCh FrancisaJCh Francisco Ch

1 1 1 1

35 A0 39

33 25

Y

Figura 10.7. La rejilla una vez vinculada al DataViewManager

Como puede ver, gracias a la clase DataViewManager es posible mantener las relaciones en las vistas de datos, principalmente en componentes de interfaz como DataGrid, sin necesidad de gestionar por separado la selecci6n de filas en cada DataView individual.

La selecci6n de parte de las filas de un conjunto de datos, obtenido previamente mediante una consulta, o la elecci6n de un orden distinto, tradicionalmente ha requerido una comunicaci6n con el servidor para facilitar el nuevo resultado. Gran podido verse en este capitulo, con ADO.NET es cias a la clase Dataview, s e g ~ ha posible conseguir esas operaciones de manera mucho m6s r6pida y sin establecer una conexi6n con el origen de datos. En realidad, programando el acceso a datos desde c6digo tal y como estamos haciendo en 10s ejemplos de 6ste y 10s capitulos previos, las vistas no son muy necesarias puesto que podemos conseguir resultados similares mediante el m6todo Select ( ) con el que cuentan 10s DataTable.A la hora de enlazar las filas con un componente de interfaz, un tema del que nos ocuparemos en un capitulo posterior, las cosas cambian, ya que no es posible vincular con un arreglo de DataRow, pero si con un DataView o un DataViewManager.

~

.. .

En el capitulo dedicado a1 estudio de 10s conjuntos de datos y clases relacionadas, DataSet, DataTable, DataRow, Datacolumn, etc., se introdujeron algunos temas relativos a1 almacenamiento y recuperacibn de 10s datos, y su informacih de esquema, en forma de documentos XML y esquemas XSD. '3610 esa posibilidad nos permite, como se vio en dicho capitulo, trabajar con datos en una aplicacih almacen6ndolos localmente, sin necesidad de ninguna base de datos ni servidor. La integracion entre ADO.NET y XML, sin embargo, puede llegar a ser mucho mds estrecha como se veri en este capitulo, haciendo posible el acceso sincronizado a 10s mismos datos desde un DataSet y en forma de documento XML. Esto posibilita, por ejemplo, la transformacih de 10s datos mediante XSLT o b&quedas m6s elaboradas que las que permite el metodo Select ( ) de un DataTable. Tambien existe la posibilidad de tratar como un Data S e t informacih alojada en un documento XML, sin que necesariamente tenga el formato propio de ADO.NET. Esto abre las puertas a la integraci6n entre aplicaciones a1 ser XML un lenguaje adoptado como estgndar mundial.

Antes de introducirnos en el us0 de las clases .NET para la creacih, lectura y manipulacih de documentos XML, vamos a hacer un rdpido recorrido por algunos conceptos de XML y otros temas relacionados, como DOM, SAX, XSL o XPath.

11. XML

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 aporta un estudio detallado de XML como el que podria encontrar en un titulo m i s especifico 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 facilitan 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 estas herramientas las conoci6 en el tercer capitulo, a1 crear 10s archivos Libros xsd y Libros .x m l .

.

Breve introduccion a XML XML es un lenguaje estiindar, cuya especificacibn podemos encontrar en la sede del W3C (http : //www.w3. org), cuyo objetivo es facilitar el intercambio de informaci6n entre aplicaciones, sin importar las diferencias entre plataformas hardware, sistemas operativos, lenguajes de programaci6n ni idioma. Algunos expertos denominan a este lenguaje como el nuevo ASCII, sistema universal de codificacih de caracteres reconocido por la priictica totalidad de 10s sistemas. Para conseguir esta compatibilidad tan amplia, XML se describe con marcas codificadas en texto simple, nada de formatos binarios mas compactos per0 incompatibles, generalmente Unicode. Esto facilita el us0 de caracteres de cualquier idioma, incluidos aquellos que, histbricamente, han estado marginados en el campo de las tecnologias de la informaci6n. En este aspecto, podriamos comparar XML con HTML, a1 ser ambos formatos aplicables de manera universal. A diferencia de HTML, sin embargo, las marcas de XML, salvo un conjunto base, no estan predefinidas. Cualquiera puede definir su conjunto de marcas o etiquetas XML y aplicarlas a sus necesidades especificas. Esta capacidad es en si una necesidad, ya que XML no se emplea para definir la apariencia de 10s datos que contiene, como es el caso de HTML, sin0 para describir su estructura. Los documentos XML son muy ficiles de leer, ya que la estructura prPcticamente se describe por si sola. En el siguiente documento, fragment0 del utilizado en el tercer capitulo como ejemplo, es ficil ver que existen dos elementos principales, Libros y Editoriales, que se repiten conteniendo informacidn de distintos libros y editoriales. Ambos elementos estiin contenidos en una raiz que, en este caso, tambien se denomina Lib ro s.



l4 84-415-1145-4 Introducci6n a l a prograrnacihn Francisco Charte l 24.04

Prograrnacidn de bases de datos con Visual Basic .NET

G 84-415-1351-l Prograrnacihn con Visual Basic .NET Francisco Charte l 39

l Anaya Multirnedia < 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>

2 McGraw-Hill < Di recci on > Ed i f i c i o Va 1re a 1t y , 1 a p 1ant a < / Di re cc ioTi>



Extensible Markup Language (XML) Core Drafts Develowei Discussion EwntslPubs (translationsl Software Test Sulte BX!!ma& 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 _ XML _ Sianature and Canonicalization

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 XML Information Sel Reourremenls Feb '99 working group XML Cure feedback ~-xI*il-infoset-cornrnents discussion e v cornw textxml %MLFraamenl lnterchanas Candidate Recommendationas of 12 February2001

.. .

Figura 11.1. S e d e del W3C dedicada al lenguaje XML

11. X M L

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 marcas de cierre, todos 10s atributos se introducen entre comillas dobles y el documento 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 documento 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 esquema XSD. Estos elementos, las DTD y 10s esquemas XSD, se utilizan para validar documentos XML y verificar que son apropiados para la aplicaci6n que debe procesarlos.

A pesar de que a partir del contenido de un documento XML, como el mostrado en el punto anterior, es relativamente fiicil deducir su estructura, si deseamos estar seguros de que 10s datos introducidos tienen 10s tipos adecuados y que la estructura es siempre la correcta, tendremos que servirnos de un documento de definici6n de tipos, conocido como DTD, o bien un esquema XSD. Una DTD es un documento, no basado en XML, en el que se describe la estructura de 10s elementos de un documento XML, asi como su tipo, si bien en este aspecto las limitaciones son bastante importantes. Un ejemplo de DTD, definiendo una estructura similar a la del documento XML previo, seria el siguiente:

< ! E L E M E N T L i b r o s (Libra+)> < ! E:LEMENT L i h r o ( I D L i b r o , ISBN, T i t - i r l o , A u t o r , E d i t o r i a l ,



c ! ELEMENT E d i t c r i a 1es ( E \ J i t (c,ria It ) > < ! KLEMENT E d I t (3r i a 1 ( I DEdi t o r i a 1, Norrtbr e , D i L e c c i o r l j >

< ! ELEMENT Nc-,mbrc ( # P C D A T A ) > < !ELEMENT Direction ( # P C D A T A ) >

P r e c i o )>

Esta definici6n puede colocarse a1 inicio del propio documento XML o bien almacenarse separadamente, en un archivo con extensi6n d t d , haciendose referencia 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 flexibles, 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

informaci6n en forma de documentos XML, por lo que debe existir un mecanismo para distinguir las etiquetas que, coincidiendo en nombre porque eso podria suceder, pertenezcan a aplicaciones o empresas distintas. Aqui es donde entran en juego 10s ambitos con nombre o namespaces, que nunca debe confundir con 10s Bmbitos con nombre de Visual Basic. Los Ambitos con nombre se asocian siempre con un URL que, por regla general, suele apuntar a un esquema XSD, aunque esto no es imprescindible. La definicion se efectua en la marca raiz del documento utilizando el atributo x m l n s . Este irB seguido, tras dos puntos, del nombre del Bmbito, disponihdose el URL tras un signo =. A partir de ese momento, 10s elementos usados en el documento se precederan del nombre del Bmbit0 a1 que correspondan, siendo posible emplear varios en un mismo documento. En el esquema XSD del punto previo puede ver c6mo se define el Bmbito con nombre xs, asociBndolo con el URL http://www.w3.org/20O1/XMLSchema,y c6mo se usa en el resto del documento como prefijo de las marcas propias de XSD.

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, generalmente 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 herramientas 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 XslTransform,aplicando una hoja de estilo XSL a cualquier documento XML que tenga alojado en un XmlDocument, o derivado, para el que exista un XPathNavigator.

*

La mayoria de las clases dirigidas a operar sobre documentos XML, esquemas XSD y emplear XPath y XSLT se encuentran en el ambito system.Xml o alguno de sus subambitos. En la figura 11.2 se han representado las clases mas representativas, cada una de ellas contenido en el ambito correspondiente. Como puede ver, el mayor numero de clases, y las de utilizaci6n mas habitual, estan en s y s tem.X m l , siendo el resto de 10s Bmbitos especificos para la gesti6n de esquemas, persistencia de datos, uso de XPath y transformaci6n de documentos, respectivamente. Como siempre, no olvide consultar la documentaci6n electr6nica de Visual Basic .NET para encontrar informacih detallada sobre cada uno de 10s miembros de &tos bmbitos. E n 10s puntos siguientes se explica el uso de algunas clases, mostrandose ejemplos practices, pero no se intenta facilitar una referencia de todas las clases y sus miembros ya que &a es una informacih que ya tiene a su alcance.

Svstem .Xml.Schema XmlSchema

XmlSerializer

II

Svstem.Xml XmlDocumen t XmlDataDocument XmlReade r

XmlElement XmlNode XmlWri ter

XslTransfo m XPathNavigator

II

Microsoft.Xml.XPath

I

Figura 11.2. Ambitos relacionados con XML y algunas de sus clases

Para leer un documento XML de manera secuencial, nodo a nodo y elemento a elemento, tenemos a nuestra disposicih las clases derivadas de XmlReade r que, en cierta manera, son equivalentes a las clases Reader implementadas por 10s

Pvogramacio'n de bases de datos con Visual Basic .NET

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 elementos, como ocurre con SAX, disponemos de un cursor solo de lectura y unidireccional, 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 Figura 11.3. Clases derivadas de X m l R e a d e r

A1 derivar de una base comun, XmlTextReader, XmlValidatingReader y XmlNodeReader comparten un buen numero de miembros. Centrdndonos en las dos primeras, que nos permiten leer un documento XML desde un flujo de datos sin o con validacih, su constructor puede tomar como primer argumento, entre otras opciones, una cadena con un camino y nombre de archivo, un Stream o un Text Reade r. Teniendo acceso a1 documento XML a recorrer, que incluso podria ser un fragmento XML preparado en memoria, el metodo Read ( ) nos permite ir avanzando por sus elementos. En cada momento, el cursor interno del XmlReader apuntard a un elemento del documento, a1 que tenemos acceso mediante multiples propiedades para, por ejemplo, conocer su tipo, nombre, prefijo si estd asociado a un dmbito con nombre, etc. Tambikn tenemos a nuestra disposicion m6ltiples mktodos del tipo ReadXXXX ( ) para leer el texto de un elemento en distintos formatos. Suponiendo que queremos tan so10 mostrar por la consola el contenido del documento XML Libros . xml,usado como ejemplo en el tercer capitulo, podriamos usar el c6digo siguiente. Como es Iogico, en la prdctica efectuariamos algun proceso de la informacion en lugar de imprimirla simplemente, per0 el proceso de recuperacion serd identico a1 mostrado aqui. 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

"

t OI-",

c

( )

L e c t o r .Name)

. N a r r i e - " L i h r c ~ " Or L e r t lc.FJritcLinc() '

L

.Name="EJitc r i d l t ' "

Then

End I f

End Select End While Li

L.C1

?

End Sub End Module

La ejecuci6n de este c6digo deberia generar un resultado identico a1 mostrado en la figura 11.4. Bdsicamente es el documento XML original, per0 no lo hemos leido directamente como si fuese un texto sino mediante un XmlReader. Esto nos permite distinguir 10s tipos de nodo y efectuar otras operaciones, como saber si el elemento tiene o no atributos, conocer su n6mero, separar el prefijo de dmbito del nombre de 10s elementos, etc. En el ejemplo anterior se ha usado NodeType para saber el tip0 de nodo, Name para recuperar su nombre, Depth para conocer la profundidad en el documento y Value para recuperar un valor de un nodo de texto. En caso de que deseemos tratar un documento XML previa validaci6n contra una DTD o un esquema XSD, en lugar de XmlTextReader empleariamos la clase XmlValidatingReader,indicando en la propiedad ValidationType el tipo de

Programacidn de bases de datos con Visual Basic .NET I

validacibn a efectuar y adadiendo el esquema a Schemas o facilitando la informacibn necesaria en XmlResolver para acceder a la DTD. IC:\P&lctVisuatBasicN~Cap-l

I\LecturaXMLWn\kturaXML.exe

ri

Figura 11.4. El documento XML procesado por el codigo de ejemplo

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

para modificar el contenido de 10s nodos, eliminar o afiadir elementos. Podriamos efectuar este trabajo manualmente en el programa, mediante codigo, y luego usar un Xmlwriter para volver a generar el documento, per0 existen alternativas m6s eficientes y simples. Una de esas opciones es la clase XmlDocument,en la que se implementa el DOM nivel 1y 2. Esta clase aloja el documento XML completo en memoria y ofrece facilidades de navegacion, lectura, modificacion, insertion y borrado. En la figura 11.5 puede ver que XmlDocument est6 derivada de XmlNode, clase que implementa la interfaz IXPathNavigable,actuando a su vez como base de XmlDataDocument, una clase que usaremos posteriormente para sincronizar la informacion de un documento XML con un DataSet.

X P a thNa vig a b 1 e

XmlDocument XmlDataDocument Figura 11.5. La clase XmlDocument y relacionadas

XmlDocument recupera todo el documento XML y genera un drbol jerarquico en memoria, compuesto por 10s nodos y elementos que existan en dicho documento. La recuperacion de este puede efectuarse desde un archivo en disco, un flujo o Stream,un XmlReader, un TextReader, etc. El metodo Load ( ) cuenta con varias versiones que aceptan distintos pariimetros, segun nos interese en cada caso. Disponiendo del documento en el objeto XmlDocument, mediante la propiedad Document Element obtendriamos el primer elemento, el que actua como raiz de todos 10s demas. Este es de una clase tambien derivada de XmlNode, por lo que, en principio, tenemos muchas de las propiedades y metodos con que cuenta XmlDocument, entre ellas: NodeType: Contiene el tip0 de nodo. Name: Aloja el nombre del nodo. 0

Value: Almacena el valor del nodo. Attributes: Atributos del nodo actual. HasChildNodes:Devuelve True si el nodo que esta tratiindose tiene nodos hijo.

0

Firstchild: Devuelve el primer nodo hijo del nodo actual.

0

ChildNodes: Recupera la lista de nodos hijo del nodo actual.

Programacidn de bases de datos con V i s u a l Basic .NET

0

0

Lastchild: Devuelve el ultimo nodo hijo del nodo actual. ParentNode: Devuelve una referencia a1 nodo que actua como padre del actual.

0

Nextsibling: Obtiene el nodo siguiente a1 actual en el mismo nivel.

0

Previoussibling:Obtiene el nodo anterior a1 actual en el mismo nivel.

0

Appendchild

0

( ) : Afiade

InsertBefore ( ) /InsertAfter ( ) : Inserta un nuevo nodo antes o despu&, respectivamente, del indicado. ( ) : Elimina

0

Removechild

0

Replacechild

0

0

un nodo hijo a1 actual.

un nodo hijo del nodo actual.

( ) : Sustituye

un nodo hijo existente por otro.

SelectNodes ( ) : Selecciona un conjunto de nodos a partir de un camino XPath. CreateNavigator ( ) : Devuelve un XPathNavigator asociado a1 documento, para recorrerlo.

Aparte de &os, heredados de XmlNode, la clase XmlDocument cuenta con multiples miembros adicionales que facilitan, por ejemplo, la creaci6n de un nodo, la obtenci6n de elementos a partir de su identificador o la escritura del documento de vuelta a un archivo o flujo de datos. Supongamos que quiere actualizar el documento XML que contiene 10s datos de 10s libros, incrementando 10s precios un 10 por ciento a1 tiempo que se muestra por consola el titulo de cada libro, el antiguo precio y el nuevo. El c6digo necesario seria el siguiente: I Module Module1

s New XmlDocurnent Dim Nodo As XrnlNode ' I'

[ )

I

Dim Titulo As String, Precio As Decimal

D o c u m e n t o . L o a d ("libros.xml" 1 v

For Each

. D o c u m e n t E l e m ~ n tChildNodes .

11. X M L

Titulo Precio

= =

Nodo.ChildNodes(2).InnerText Nodo.ChildNodesi5).InnerText l l r 5 i ->

Nodo.ChildNodes(5).InnerText End If

12r51"r

Precio

=

Next 1

I_

I

D o c u m e n t o . Save "NuevosPrecios . x m l "

)

End Sub End Module

Tras recuperar el dLcumento XML, mediante el metodo -oad ( ) , ob-memos la lista de nodos existentes en el elemento principal. DocumentElement es ese nodo principal, , y ChildNodes nos ofrece la coleccidn de todos 10s XmlNode que contiene. Comprobamos si el nodo corresponde a un libro y, en caso afirmativo, recuperamos el texto que hay en las columnas tercera y ultima, titulo y precio. Una vez mostrados en la consola, actualizamos el precio y lo asignamos a1 nodo. Finalmente, guardamos el documento en un nuevo archivo. En la figura 11.6 puede ver el resultado generado por el programa, y en la figura 11.7 aparece el documento NuevosPrecios . xml en Internet Explorer, con 10sprecios ya modificados.

Figura 11.6. Resultado producido por el programa

Prograrnacio'n de bases de datos con Visual Basic .NET

Dim Docurnento As New X m l D o c r J r n e r ~ t( 1 D o c u m e n t o . Load ( " L i b r o s . x r n l " ) Dim N a v e g a d o r As X P a t h N a v i g a t o r = Documento.CreateNavigator

( )

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 = N a v e g a d o r . Select ( " / I , i b r ' r / L i b r o [ E d i t o r i a l = l ]/ T I t u l o " ) ~

CrL f , Re c u 1t a d o . C o u n t 1

teLi

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

Figura 11.8. Lista de titulos de la editorial con codigo 1

__

__

-I_^_

__- -

-

--

Los documentos XML pueden ser transformados en documentos de otro tipo, segun se anotaba en un punto previo, gracias a XSLT. El proceso se basa en la construcci6n de una plantilla XSLT que, tras ser procesada por el analizador XSLT, genera el nuevo documento a partir de la informaci6n de origen. En esa plantilla se combinan expresiones XPath, para seleccionar 10s datos, con instrucciones de proceso XSLT tales como template, for-each o value-of. Este lenguaje, como todo lo relacionado con XML, se encuentra definido en especificaciones del W3C y

11. X M L

cuenta con sentencias condicionales y de repeticibn, como 10s lenguajes de programaci6n. El documento mostrado a continuaci6n es una plantilla XSLT para transformaci6n de documentos, concretamente para generar una tabla HTML con el nombre y precio de 10s libros del documento XML de ejemplos previos:

Las dos primeras lineas son las que identifican a1 documento como una plantilla XSLT u hoja de estilo XSL. Todas las instrucciones XSLT van precedidas con el prefijo xsl, como puede apreciarse. La marca aplica la plantilla que hay a continuaci6n, hasta la etiqueta de cierre ,a todos 10s datos del documento, ya que la expresi6n XPath del atributo match selecciona todo su contenido. A continuaci6n encontramos marcas HTML corrientes para la creaci6n de una tabla. La etiqueta es equivalente a un bucle For/Next de Visual Basic, repitiendose tantas veces como elementos Libro existan en la rama Libros. 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 antes. Finalmente, en el interior de las celdillas de la tabla HTML se introduce el valor de dos elementos de cada libro, leidos con . 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 directamente 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. Previamente, 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

El metodo Transform ( ) puede tomar distintas listas de pardmetros, siendo el formato mhs fhcil el que tan s610 toma dos cadenas de caracteres conteniendo el nombre, incluyendo camino si es necesario, del archivo XML de origen y el archivo de destino. Otras opciones nos permiten usar flujos de datos, XmlPathNavigat o r como origen, etc. Asumiendo que tenemos la plantilla de transformaci6n anterior almacenada en un archivo llamado TablaHTML. x s l t , con el sencillo programa mostrado a continuaci6n generariamos el documento HTML que puede verse en la figura 11.9. No es espectacular, pero s610 seria precis0 afiadir algunas marcas mhs a la plantilla para introducir un titulo de pdgina, una tabla mhs vistosa o mas informacion de la contenida en el documento XML. El resultado se adaptaria automhticamente a 10s cambios de la plantilla, sin que tuvi4semos que modificar el programa. Tambien existe la posibilidad de crear la plantilla XSLT a1 vuelo, en el propio programa, produciendo a partir del documento XML otro formato de documento sin necesidad de procesar elemento a elemento todo su contenido. 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 hacen posible la lectura y manipulaci6n de documentos XML desde cualquier aplicaci6n desarrollada con Visual Basic .NET, sin importar su finalidad. Muchas de las operaciones descritas, no obstante, encuentran su mayor aplicaci6n en nuestro caso, 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 adecuados, 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

DataSet para su presentacion a traves de la Web. Podriamos usar vistas, consultas SQL y generar 10s documentos mediante ASF'.NET pero, en ciertos casos, el us0 de XPath o XSLT pueden ser mejores opciones. El caso inverso tambien puede darse. Podemos obtener un documento XML desde una aplicacion externa, por ejemplo a traves de Internet, y, mediante la sincronizacion con un DataSet, manipular su contenido como si se tratase de un conjunto de tablas de datos.

&rihiio

Edcian

yer

Faioitos

!erramentar

I

;

,

a/&

Burqueda

Fa,

Cap-1 liiransfolmacion bm eeiultado ~

-

I _

hlanual del iiiicropiocssador 80386 40 Inttoduccioii a la piogxarnacioii 34 04 Guia practica pata uauariob de KjIir 10 5 2 Guia practica para usuaiios d2 Excel 2002 10.51 hIaiiual aLanzado Excel 1001 1 1 04 Guia piactica pata us~iaiiohde Delphi 6 10 5 2 Programacion con Delphi 6 1 KJ hi 3' 26 Guia practica pata muaiio5 de T'isual Studio NET 10 5 2 Guia piactica paia usuaiiob d2 T'iaual Basic YET 1 1 2 . ~ 5 Piogratuacion con T'imd Bahic NET 39 Piogianiacion coil \*iaual \hidlo YET 40 Progiatuacioii con Yibual C NET 39 Guia practica paia usuaiios JBuildcr 10.'5 L'aei Interface Dshigii for Propianinisrs 31 EQL \ m e i 2000 10 -5

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 Dataset 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

El procedimiento de trabajo vinculado entre DataSet y XmlDataDocument puede desarrollarse, principalmente, de dos formas distintas:

1. Creacion del Data S et vacio, recuperaci6n de informaci6n de esquema, ya sea leyendola de una definici6n XSD o bien cre6ndola segun se vio en un capitulo previo, y lectura de la informaci6n desde un documento XML a traves del Xml Data Document. 2. Creaci6n del Data S et con informacibn, ya sea obtenida mediante un adaptador o aiiadida por otros medios, creando a continuaci6n el XmlDataDocumen t vinculado a1 Data S e t.

Vamos a ver 10s dos procedimientos con un breve ejemplo en 10s dos puntos siguientes.

El primer caso se dar6 cuando la informaci6n se nos facilite en formato XML, por ejemplo procedente de una aplicaci6n externa a traves de una red, y necesitemos introducirla en un Data S et para poder tratarla como un conjunto de tablas y, si nos interesase, incluso conectarla con componentes de interfaz de usuario. Puede pensar que podriamos guardar la informacidn en formato XML en un archivo y, posteriormente, recogerlo desde el Da taSet mediante el metodo ReadXml ( ) . Puede hacerse, per0 con el inconveniente de que no se respeta el formato original que tuviese el documento XML. Si hacemos cambios y luego guardamos la informaci6n con W r i texml ( ) , nada nos garantiza que el orden de 10s elementos, sus atributos y la estructura con que estaba escrito, por ejemplo separaciones y espacios en blanco, vayan a mantenerse. Leyendo el documento en un XmlDataDocument estaremos seguros de que la estructura se mantiene, a1 tiempo que conseguimos el acceso desde un Data S et . Puede comprobarlo con el siguiente programa de ejemplo: 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 ( )

Dim Datos As New Dataset() 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

1)ocumerito.Load ( " L i b r o s.xrnl")

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

For Each Tabla In Datos.Tables Console.WriteLine(Tabla.Tab1eNarne & vbCrLf) For Each F i l a In Tabla.Rows For Each c o l u m n a In Tabla.Columns Console.Write( F i l a ( c o 1 u r n n a ) & vbTab) Next c o n s o l e . W r i t e I , i ne ( Next Console.WritoLine ( ) Next

)

End Sub End Module

Tras crear el Data S e t vacio, recuperamos la informacih de esquema del archivo L i b r o s . x s d creado en el tercer capitulo. De no disponer de este archivo tendriamos que obtener la estructura de algun otro modo, ya sea definiendolo mediante cddigo, porque lo conozcamos de antemano, o bien deduciendolo del contenido del propio documento XML. A continuacih creamos el XmlDataDocument.Observe c6mo se pasa a1 constructor el DataSet r e c i h creado. Acto seguido damos a la propiedad EnforceConstraints del DataSet el valor False,ya que durante la lectura del documento, que se efectua en la sentencia siguiente, las restricciones de las columnas podrian no ser vdidas y generar excepciones. Finalmente, se lee el documento XML y muestra por consola el contenido del DataSet.El resultado serd similar a1 de la figura 11.10. En vez de escribir 10s datos, como en este ejemplo, podriamos modificar, insertar, aiiadir, etc., y despues devolver la informacih a1 documento XML con el metodo Save ( ) de la clase XmlDataDocument.

-~

Este proceso es acin mfis simple si cabe, ya que basta con crear el XmlDataDocument 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 aplicar una transformacih a 10s datos para generar un nuevo documento. Son posibilidades que ha conocido brevemente en puntos anteriores.

Programacidn de bases de datos con Visual Basic .NET

4

Figura 11.10. LOS datos obtentdos del D a t a S e t a traves del XmlDataDocument

A mod0 simplemente de ejemplo, el programa siguiente crea un D a t a Se t y lo llena, mediante un adaptador de datos, con el contenido de la tabla L i b r o s que teniamos en la base de datos SQL Server. A continuaci6n crea elXmlDataDocument y lo muestra por consola. Por ultimo, usando un X P a t h N a v i g a t o r , se localizan todos 10s titulos de libros pertenecientes a la primera editorial. Observe la expresidn XPath, en la que la raiz es M i s D a t 0 s ya que &e es el nombre que hemos dado a1 D a t a S e t , mientras que L i b r o s es el nombre de la tabla. Imports Imports Imports Imports

System.Xm1 System.Xml.XPath System. Data System.Data.SqlC1ient

Module Module1 Sub Main()

'

Jr!il;il;lG.,:

li;!a

.

I

cznl;.XIL7li

D i m Conexion As N e w SqlConnection(

-

"Data Source=inspiron; Initial Catalog=Libros; "User ID=sa; Password=") I i 11' ? a 3' dLJL' D i m AdaptadorLibros As N e w SqlDataAdapterl "SELECT FROM Libros", Conexion) I ,-. - ,j,, ..., l , , L % s . : 1 p3t_.s::.it D i m Datos As N e w DataSet("MisDatos") I._i

-

"

& -

11. X M L

Dlm N a v e g a d )r As XPathNavlgatoL

=

Dacumeritr X r e a t e N a v i g a t o r [ )

Di ~

[ E j i t o r i d 1= 1 ]

Console.WriteLine("Hay { O } t i t u l h s "

&

/ T 1t ul o " 1

vbCrLf, Resultado.Count)

E n d While E n d Sub E n d Module

A1 ejecutar el programa, y asumiendo que la conexi6n con el origen de datos es satisfactoria, ver$ en un primer momento, como aparece toda la informaci6n por la consola en formato XML. Tras pulsar Intro se enumeraran 10s titulos de 10s libros pertenecientes a la primera editorial, como se aprecia en la parte inferior de la figura 11.11.Puede ampliar el programa, o basarse en 61 para crear otro, con el fin de que se aplique una transformaci6n generando una tabla HTML con 10s datos de 10s libros.

Como ha podido ver en este capitulo, especialmente en 10s ultimos puntos, la integraci6n entre XML y ADO.NET es tan estrecha que 10s conjuntos de datos pueden tratarse como documentos XML, y viceversa, con gran simplicidad. Los beneficios que se obtienen son muchos, ya que 10s conjuntos de datos pueden producir flujos de datos XML adecuados para ser remitidos a aplicaciones externas, que no trabajan con ADO.NET, invirtihdose el proceso cuando es nuestra aplicaci6n la que actua como receptora. La posibilidad de enviar conjuntos de datos en formato XML tambien es util entre aplicaciones .NET, por ejemplo entre un servicio Web y una interfaz o entre un componente de negocio que se ejecuta en un servidor de aplicaciones y un cliente

I

Programacidn de bases de datos con Visual Basic .NET

remoto. En casos asi el conjunto de datos se convierte en XML para ser transmitido por la red, invirtihdose el proceso en el destino.

Figura 11.11. Documento XML generado a partir del D a t a S e t y resultado de la seleccion XPath

11. X M L

Por ultimo, no hay que menospreciar la posibilidad de emplear tkcnicas como XPath y XSLT sobre informacih almacenada en un Data S e t, como se ha demostrado en el ultimo punto. En ocasiones una busqueda de datos, conociendo XPath con detalle, puede ser mucho m i s eficiente a travks de un XmlDataDocument que creando vistas o usando el metodo Select ( 1 de 10s DataTable.

Los capitulos de la segunda parte, que acaba de finalizar, le han servido para conocer un gran numero de clases de ADO.NET, aprendiendo a utilizarlas en el codigo de sus programas sin recurrir a asistente o herramienta de diseiio alguna. Saber qu4 clases son las que se emplean y c6mo funcionan es importante, cuando surgen problemas imprescindible para resolverlos, per0 tambien es cierto que las herramientas de disefio de Visual Studio .NET pueden ahorrarnos gran parte del trabajo que, hasta ahora, ha efectuando escribiendo c6digo. El objetivo de esta tercera parte del libro es mostrarle c6mo usar el entorno de Visual Studio .NET, del cual forma parte Visual Basic .NET, para definir conexih, crear conjuntos de datos con comprobaci6n de tipos, generar adaptadores de datos, acceder a la informaci6n desde el propio entorno, etc. Ser6 el tema de 4ste y 10s pr6ximos tres capitulos. Las posibilidades o capacidades que encontraremos en el entorno, relativas a1 trabajo con datos, ser6n unas u otras dependiendo de la edicion con la que contemos. Ese ser6 el aspect0 que tratemos en este capitulo, de tal forma que sepa cu6les de 10s elementos explicados en 10s capitulos siguientes tiene o no a su disposici6n.

Como probablemente sabr6, Visual Basic .NET es un product0 que puede adquirirse 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 ediciones siguientes:

Visual Basic .NET Standard: Es la edicion m6s simple y unica que puede adquirirse 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 incluye 10s lenguajes Visual C# .NET, Visual C++ .NET y Visual J# .NET, asi como capacidades inexistentes en la edicion anterior: Crystal Reports, herramientas visuales de bases de datos, herramientas de diseiio para el servidor que facilitan el acceso a servicios, bases de datos, etc. Puede obtenerse una version de prueba de esta edicion, limitada a 60 dias, solicitiindola en la Web de Microsoft. Visual Studio .NET Enterprise Developer: Seguramente la edicion m6s apropiada para el desarrollo de aplicaciones con necesidades de acceso a bases de datos, ya que incorpora todas las herramientas de diseiio necesarias y algunos 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 version especifica de Visio para el modelado de bases de datos y aplicaciones y el producto Microsoft BizTalk Server para la construccion de procesos de integracion con aplicaciones de clientes, proveedores o socios. Adem6s de &as, que podriamos calificar de ediciones comerciales, tambien existe un Visual Studio .NET Academia dirigido a estudiantes y profesores. Sus caracteristicas son similares a las de la edici6n Professional, si bien incorpora algunos elementos adicionales y especificos para la audiencia a la que se dirige.

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.microsoft.com/vstudio/howtobuy/choosing.asp.

Programacidn de bases de datos con Visual Basic .NET

MlCmsofr

Visual Basicnet Standard Figura 12.1. Caja de Visual Basic .NET Standard

Figura 12.2. Caja de Visual Studio .NET Enterprise Developer

Los mecanismos de acceso a datos de la plataforma .NET, todas las clases ADO.NET que hemos conocido en 10s capitulos previos, no forman parte de un lenguaje o una edici6n de Visual Studio .NET en particular, sino de la propia BCL que existe en cualquier instalaci6n .NET y que, por ejemplo, encontramos ya como parte del sistema en el nuevo Windows .NET. Las posibilidades de acceso a datos de nuestras aplicaciones, por lo tanto, son independientes de la edici6n de Visual Studio .NET que vayamos a emplear para

12. Capacidades de datos en Visual Studio .NET

10s desarrollos. Las diferencias, Mgicamente, las encontraremos en el entorno de trabajo, ya que muchas de las operaciones efectuadas mediante ddigo, o con las herramientas de administraci6n especificas de cada origen de datos, en las ediciones superiores de Visual Studio .NET pueden realizarse desde el propio entorno. Lo que si resulta imprescindible es disponer de 10s controladores y proveedores adecuados para nuestras aplicaciones, pudiendo ser necesaria, por ejemplo, la instalaci6n de 10s MDAC o 10s proveedores para ODBC u Oracle, en caso de que dependieramos de ellos.

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 productos son MSDE, Microsoft SQL Server 2000 y Microsoft Visio. Con la edici6n m6s baja, la Professional, disponemos de MSDE que, como se indic6 en su momento, es, bisicamente, el motor de SQL Server per0 sin herramientas 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 Microsoft 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 necesidades 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 producto 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 modelado basadas en est6ndares para construir nuestros modelos de bases de datos y negocio.

Para facilitar el trabajo con bases de datos, en el sentido m i s amplio de la palabra, Visual Studio .NET integra una serie de herramientas que son conocidas genericamente como Visual Database Tools. La mayor parte de ellas son accesibles desde el Explorador de servidores que, como puede verse en la figura 12.3, nos permite definir conexiones con origenes de datos y acceder directamente a estos, asi como conectar con servidores para ver qu6 servicios tienen disponibles.

Programacidn de bases de datos con V i s u a l Basic .NET

insplron pubs.dbo2

-

'8Diagramas de base de datos IBTablas +

17 CS-SRS(MDSYS) 0

MDDICWER (MDSYS)

0 OGIS-SPATIAL-REFEFENCE-SYSTEMS 17 ME-PROYYINFO +

(MDSYS)

[MTSSYS)

0 DEPT 0 0

EDITORIALES 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

Figura 12.3. Aspect0 del Explorador de servidores

Dependiendo de la edici6n de Visual Studio .NET con que contemos, las capacidades de estas herramientas visuales serin unas u otras. Resumidamente podriamos decir que: 0

0

0

En las ediciones Standard podemos explorar las conexiones para ver el contenido de las tablas de bases de datos Access y MSDE. La edici6n Professional tambien nos permite explorar servidores SQL Server y cualquier origen con un controlador ODCB u OLE DB, asi como diseiiar tablas y vistas sobre MSDE. 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 existir en un RDBMS como SQL Server u Oracle.

12. Capacidades de datos e n V i s u a l Studio .NET

Los proveedores ADO.NET nativos para Oracle y ODBC aparecieron despues de que Visual Studio .NET estuviese disponible, por ello desde el Explorador de servidores, en las ediciones superiores, puede accederse nativamente a un servidor SQL Server para operar sobre el, o a cualquier origen para el que exista un proveedor OLE DB, per0 no puede hacerse lo mismo con Oracle. Nada nos impide, sin embargo, acceder a una base de datos Oracle usando el proveedor OLE DB correspondiente, aunque en el codigo despues utilicemos el proveedor O r a c l e C 1i e n t .

I Asumiendo que estamos trabajando con una de las ediciones Enterprise de Visual Studio .NET, en 10s capitulos siguientes se abordard el us0 de las herramientas 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 herramienta de administracidn propia de cada producto. Generaci6n automatica de conexiones a origen de datos, adaptadores de datos 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 consultas, 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 interfaces 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 importante del c6digo que en 10s ejemplos de capitulos previos introduciamos manualmente, 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.

Ha de tener en cuenta que, en caso de que utilice la edicion Professional de Visual Studio .NET, o VisualBasic .N€TStandard, algunos de 10s procedimientos en 10s capitulos siguientes pueden no estar disponibles en su instalacion del producto.

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 siguiente.

En 10s ejemplos desarrollados en 10s capitulos de la segunda parte hemos conectad0 con diferentes origenes de datos, recuperado informaci6n mediante objetos DataReader, ejecutado comandos, llenado DataSe t con informaci6n de esos origenes a traves de adaptadores de datos, generado automAticamente 10s comandos de actualizacibn, etc. Todas esas acciones las hemos implementado escribiendo c6digo, lo cual nos ha servido para conocer muchos de 10s detalles de las clases implicadas, 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, produciendo 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 herramientas 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 te6rico 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 explicaciones.

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 proveedor 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

% Servlclor

f

I.

+ +

Serviuos de Crystal

‘1 Seriidores SQL Serler

Figura 13.1. Aspect0 inicial del Explorador de servidores

If

1 ----

Crear p e v a base de d a b s SQL Server

-

-

Figura 13.2. AAadimos una nueva conexion al Explorador de servidores

13. Herramientas visuales de datos

Figura 13.3. Ventana Propiedades de vinculo de datos

Seleccione de la pdgina Proveedores el proveedor Oracle Provider for OLE DB, introduciendo en la pAgina Conexion el nombre del servicio local Oracle que cre6 con el software cliente, asi como el nombre de usuario y la clave. En 10s ejemplos de capitulos previos el servicio era L i b r o s , el usuario s c o t t y la clave t i g e r . Pulse el b o t h Probar conexi6n para asegurarse de que 10s pardmetros son correctos y, finalmente, pulse el b o t h Aceptar para finalizar la definici6n de la conexi6n.

Tras crear una conexion con un RDBMS es posible que, al desplegarla en el Explorador de soluciones, aparece una ventana solicitandole la identificacion. lntroduzca el mismo nombre de usuario y clave que us6 a1 definir la conexion.

El nombre con el que aparecerd la nueva conexi6n, en el Explorador de servidores, ser6 una combinaci6n del identificador de servicio y el nombre del usuario, como se aprecia en la figura 13.4. A1 desplegarla ya tenemos acceso a todo el contenido de la base de datos desde el propio entdrno de Visual Studio .NET, sin necesidad de usar el software cliente de Oracle.

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

+ + + + +

-

Diagramas debase de dabs ‘$Tablas

& smonimos

i& v1stas Procedtmientos ahacenados + b Funomes + Espafieoones del paquete + @ Cuerpos de paquete Servidores @ dimension + & Colas de mensajes + Contadores de rendimiento + @, Regirbos de eientos + Sermos + f.Sermos de Crystal + ‘9 Sei.idores SQL Server

B

a %

Figura 13.4. Al desplegar la conexion aparece una lista de carpetas con objetos existentes en el origen de datos

Si el origen de datos sobre el que vamos a trabajar es SQL Server, no necesitamos definir una conexi6n para acceder a 61. Los servidores SQL Server aparecen como elementos en el nodo Servidores SQL Server del equipo donde se encuentren. Si tenemos nuestro servidor ejecutandose en el mismo equipo donde estamos usando Visual Studio .NET, no tenemos m6s que desplegar dicho nodo para acceder a las bases de datos. En caso contrario, si SQL Server se encuentra en una maquina distinta, tendremos que registrarla como un nuevo servidor. El proceso es realmente sencillo: haga clic con el boton secundario del raton sobre el elemento Servidores del Explorador de servidores y elija la opci6nAgregar servidor. En la ventana que aparece, similar a la mostrada en la figura 13.5, simplemente introduzca el nombre de la maquina 0, si lo prefiere y la conoce, directamente su direcci6n IP. A partir de ese momento, siempre que en dicha otra maquina tenga las credenciales apropiadas, podr6 operar sobre el nuevo servidor de forma remota, aunque se encuentre a miles de kil6metros. En mi configuraci6n particular, Visual Studio .NET se ejecuta en un ordenador llamado Dimension, mientras que SQL Server lo hace en otro llamado Inspiron. Por ello, para usar desde Visual Studio .NET las posibilidades de diseiio que me ofrece el Explorador de servidores, he de registrar lnspiron como servidor adicional. Hecho esto tengo un acceso completo al servidor SQL Server que se encuentra en esa otra maquina, segun puede verse en la figura 13.6. En ella se aprecia c6mo se ha conectado con el servidor y desplegado la base de datos L i b r o s , en la que aparecen varias carpetas.

13. Herramientas visuales de datos

Ep$o

&e

& senidor

Figura 13.5. lntroducimos el nombre del servidor a registrar

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

En caso de que no aparezca en el nodo Servidores SQL Server la instancia del RDBMS que deberia aparecer, puede utilizar la opcion Registrar instancia de SQL Server, facilitando el nombre del servicio. Esto, normalmente, no suele ser necesario a menos que tenga varias instancias de SQL Server 2000, cada una con su nombre de servicio, ejecutandose en la misma maquina.

~

I

-

I

-

~

~

-

~

~

~ l _ ~ l _ _ ( ~ l _ _ _ ” l _ ” . ~ - ~ ~ ” . - l _ l l _ _

L-.-_^_(

.

Para acceder desde el Explorador de servidores a1 contenido de un origen de datos, ya sea SQL Server o cualquier otro para el que hayamos definido una co-

Programacidn de bases de datos con Visual Basic .NET

nexi6n mediante OLE DB, es necesario establecer una conexi6n. Esta se abre, normalmente, 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 dicho 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.

__I I ____

- ___-

-

Conemones de datos

Figura 13.7. La misma conexion en 10s dos estados, abierta, a la izquierda, y cerrada, a la derecha

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 permite crear una nueva base de datos desde el propio Visual Studio .NET, sin necesidad 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 Explorador 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.

En ambos casos aparecerd el mismo cuadro de didlogo, si bien con la primera opci6n tendriamos que indicar el servidor donde va a crearse la base de datos y con la segunda no es necesaria, puesto que hemos empleado el menu emergente del servidor sobre el que recaerd la acci6n. Adem6s tendremos' que introducir el nombre de la nueva base de datos, que ser6 creada y quedard como una nueva conexi6n disponible, si empleamos la primera alternativa, o simplemente como otra base de datos en el servidor, de haber usado la segunda.

13. Herramientas visuales de datos

Conexiones de dams

+

-

a

dimenson

+

hlf Colas de mensajer

Inrpron 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

A partir de la creacih, la nueva base de datos queda en el Explorador de servidores como una nueva conexi6n o una nueva base de datos, segtin el caso, tratindose desde ese momento como cualquier otro de 10s elementos que ya existiesen con anterioridad. Los procesos descritos en 10s puntos previos, por tanto, son aplicables de manera indistinta.

Durante el desarrollo de una aplicaci6n es habitual la necesidad de editar directamente 10s datos alojados en el origen, ya sea para preparar un bloque de datos de prueba, simular posibles fallos o corregir 10s que pudieran generarse. En cualquier caso, casi siempre se recurre a una herramienta especifica del origen para efectuar ese trabajo. Asi lo hicimos en el tercer capitulo, a1 emplear Microsoft Access para introducir informaci6n en una base de datos Access o las herramientas de administracibn de SQL Server y Oracle para hacer lo propio sobre esos RDBMS. En realidad, una vez definida la estructura de la base de datos, no necesitibamos emplear ninguna de esas herramientas para editar la informacih puesto que, como va a ver de inmediato, es algo que puede hacerse directamente desde el entorno de Visual Studio .NET. En realidad, tampoco para definir la estructura precisamos m i s que este entorno si tenemos una de las ediciones superiores de Visual Studio .NET. Si tiene acceso a un servidor SQL Server, registre el equipo en la rama Servidores del Explorador de servidores, despliegue el servidor de datos y seleccione, de

Programacidn de bases de datos con Visual Basic .NET

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 definir 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 actuales 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 mediante el proveedor OLE DB.

CESS C VBddviwaiBaxNEl I

-

+

$VStaS

t

@ Procedimientor aimacenado

)biibroi5cm + hagramas de bare de datw

ACCOUhTNG

NEW YORK

SALES OPERATIOFIS

CHICAGO BOSTCA

I1 I

I

+

+ +

+ +

0

BONUS c ] D m EDIIORIKES €MP LlBRO

n -

+ +

LlBROS

0

RECEIPT

X

10.75 10.71 39 .10

39 10.75 10 52 37.24 10.52 21.04 10.52 1U,52 24,04 .10

Figura 13.9. Edicion de tablas de datos en el entorno de Visual Studio NET

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, obtendremos 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 u1tima que tiene datos, apareciendo automiticamente una fila vacia en la que podemos 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 automaticamente. Tampoco podra editar aquellas columnas cuya precision exceda unos ciertos limites.

En lugar de efectuar todas estas operaciones mediante teclas o combinaciones de teclas, tambien podemos abrir el menu emergente (vease figura 13.10) y seleccionar la acci6n que deseamos ejecutar. La opci6n Fila nos permite ir directamente a una cierta fila introduciendo su numero. Las tres anteriores van a la primera fila, a la ultima e insertan una nueva fila, respectivamente. Las que hay detras facilitan la copia y el pegado de datos o filas completas, por ejemplo para llenar ripidamente una tabla.

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 figura 13.11, existen multiples botones con 10s que podemos ocultar y mostrar distintos 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 indicaci6n de su finalidad.

1x

3

a 4 4 1 5 1136 S

SOL Server 2000

3.1-115 1324 4

Guia piacbca paia usuanos JEuilder 7

Franuaco Charte R a n o x n Charte Franuscn Charte/lnrge Seriano Francisco Charte Franuzco Charte Franosco Charte Franosco Charte FrancEcn Charte Franorco Charte Franosm Chartem Jesus Luque Franorcn Chatte Franosco Charte Chris ti Pappas&WiliiamH Murray, I11 l e f f Duntemann Oscar Gonzak:

8 W 1 5 1392 9 84415 1376 7 34415-1351-1 34415 1290 6

84415-1B1-1 84-115 1261 2 84 415 12558 84415 1230 2 8.1415 1202 7 84-115-1132-2 84 415 11454 847615 234 5 0-171 37523 3 34415 1402 X

1

10,75

1 1

10.75 39 w 39 10,75

1 1 1 1 1 1 1 1 1 1 2

nsz 37.26 10.52 21.04 10.52 10,52 24,04 40

1

m.5

1

10.75

Figura 13.10. Menu en el que encontramos las operaciones mas habituales

_ __ k a ~QI -.__-

gavharbpo-

!

%L

'_

~

EZ

a

Figura 13.11. Paleta de botones activa durante la edicion de datos

Tras haber hecho doble clic en la tabla L i b r o s , para abrir la correspondiente cuadricula, pulse el b o t h Agregar tabla (ultimo de la paleta indicada antes) y seleccione de la ventana que aparece (vease figura 13.12) la tabla Editoriales, pulsando el b o t h Agregar, primero, y el b o t h Cerrar, a continuacicin. En principio lo unico que notar5 es que 10s datos de la tabla L i b r o s , que ya estaban visibles, aparecen en gris. Pulse el b o t h Ejecutar consulta, cuyo icono es un signo de admiraci6n. Ver6 que la tabla de datos mostrada cambia, apareciendo en cada fila, aparte de la informaci6n del libro en cuesticin, todos 10s datos de la editorial correspondiente. Fijese en la figura 13.13 que la editorial mostrada a la derecha es la correspondiente a1 c6digo de editorial de cada libro, a pesar de que no hayamos indicado explicitamente esa vinculaci6n entre ambas tablas. Su estructura, sin embargo, indica q u e L i b r o s .EditorialesunaclaveexternaqueapuntaaEditoriales.IDEdit o r i a l , asi que Visual Studio .NET no necesita saber mhs.

13. Herramientas visuales de datos

I)

Figura 13.12. Agregamos la tabla E d i t o r i a l e s

,%to

Figura 13.13. Resultado obtenido tras aiiadir la tabla E d i t o r i a l e s y ejecutar

de nuevo la consulta Si no pretendemos editar 10s datos, sin0 simplemente efectuar alguna comprobacidn, posiblemente no necesitemos tener visibles todas las columnas. Puede pulsar el b o t h Mostrar panel de diagrama, el primer0 contando desde la izquierda, para abrir un esquema visual en el que se aprecia la relacidn entre ambas tablas y, ademAs, puede marcar y desmarcar las columnas que desea tener visibles. Una alternativa es pulsar el b o t h Mostrar panel SQL y editar directamente la sentencia SQL que se desea ejecutar. Para ver el resultado, como en el caso anterior, tendri

Programacion de bases de datos con Visual Basic .NET

que pulsar el b o t h Ejecutar consulta. En la figura 13.14 puede ver el Panel de diagrama, en la parte superior; el Panel SQL, en el drea central, y el Panel de resultados 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 panel 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

SELECT

Lbrbros 1SBI.l L r b r m Tihrlo Libros Frecio Editoriales Nombre Edturiales ON Lbbros Editutial = Editmale: IDEd tmal

15 1136 5 ? $15 13241 4-41: 1392 9 $415 1170 7 1415 1351 1 -!-+I5 1290 6

SQL Server 20 Gum prarbca para USUailOs JBulder 7 Programaoon con lisual C 2 NET Programaoon con visual Studio NET Frugrmaoon con visual Basic NET G m paCbca wra U S U ~ ~ ~de D SI wal Bavc NET

4115 120 1 2

Frogiamaclon i o n Delphi 6

4 4 1 5 1230 2 ? 115 l2n2 7 4-315 11'2 2 4415 1115 4 I7615 23+5

Manual abanrado Excel 2ui Guia pacbca para uwams de Excel 2nn2 Guia pracbca para usuarius de Yb+ihl lnboducoon a la programacion Manual del micropmesador 80386 Assembly Language Step-bf Step

471 37523 3

39

40 39

1G.75 10 52 37 26 10 52 21 04

10 5 2 10 52 2.) 04 40

6iJ 5

m a y a Mulbmeda Anaya Mulbmedia Anaw Multimedia m a y a Mulbmedia Anam Mulbmedia Anaya Mulbmedia Ana,a Mulbmedia Anaya Mulemedia AnajaMulbmcda Anwa Mulemedia M a y a Multimedia McGran+ll Anma Multimedia

Figura 13.14. Seleccion de columnas mediante el Panel de diagrama y el Panel SQL

Nota Si mantiene abierto el Panel SQL, a medida que haga cambios en el Panel de diagrama y Panel de cuadricula podra ir viendo como se reestructura la sentencia SQL que ejecutara a1 pulsar el boton Ejecutar consulta.

13. Herramientas visuales de datos

lReaa

;

1 8 484415 4 1 5 1132 1202 27

,I

;I uj

84415 1290 6 84415 12914 84415 13244 84415 1145-4 84415 1230 2 84415 1261 2 84415 1351 1 84415-13924 84415 1136 5 1893115 94 1

Guia paiaca w r a usuanos de Excel 2002 Gum pacbca para uwanos de Kdix Guia pacbca para uwarios de Visual Baac NET Guia pacbca para uylanos de Visual f b d i o NEI Gua pactlca para uwarios JBulder 7 Inmducoon a la pogramaoon Manual atanzado Excel 2002 Progtamwon con Delphi 6 y Kylh Programanon CM Visual Baa< NET Progiamaaon imr Visual C;

NET

SQLferier 2000 User Interface k s g n for Programmers

lEditmd

10.52 10,52 10,52 10 75 10.52 10 75 24,04 21,04 37,Z 39 39 10,75

h y a Mulhmedla Anaya Mulbmedia Anaya Mulbrnedra Anaya Mulbmedia Anaya Mulbmeh Anaya Mulbmedia Anaya Mulbmeda Anaya Mulbmeha Anaya Mulbmedia Anaya Mulbmedia Anaya Mdbmedia Anaya Mulbmedia

31

np-ess

Figura 13.15. Establecernos filtros de seleccion de datos y criterios de ordenacion

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 consulta para recuperar todas las filas y columnas de la tabla. Con 10s elementos indicados 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 eliminaci6n. 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 ejemplo, la eliminacih de 10s datos.

I INTO Editonales Editonales =

__

-

Edtoriales

i

M I

a

Figura 13.16. Modificamos el tipo de sentencia SQL

Si tiene como parte de la consulta alguna expresi6n de resumen, puede agrupar las filas de datos segun el valor de una cierta columna para obtener un resultado agrupado. Partiendo desde el Explorador de servidores, y asumiendo que aun no ha abierto ninguna tabla, puede hacer una simple prueba dando estos pasos: Haga doble clic sobre la tabla Libros para abrirla. 0 0

Pulse el b o t h Agregar tabla y seleccione la tabla Editoriales. Abra el Panel de diagrama y seleccione de la tabla Editoriales la columna IDEdit o rial.Teniendo &a seleccionada, pulse el b o t h Orden ascendente, estableciendo asi un criterio de ordenacih.

23. Herramientas visuales de datos

0

0

Pulse el b o t h Agrupar por, el penultimo de la barra, mientras mantiene la selecci6n en la misma columna I D E d i tori a 1. Por ultimo, pulse el b o t h Ejecutar consulta.

El resultado obtenido deberia ser similar a1 de la figura 13.17. La primera columna de resultados es el numero de titulos que tiene cada una de las editoriales, cuyo c6digo aparece en la segunda columna. Puede usar el Panel de cuadricula para asociar alias a estas columnas, asi como para cambiar el orden en que aparecen en la cuadricula de resultados simplemente arrastrando y soltando.

Figura 13.17. Resultado obtenido al agrupar por la columna I D E d i t o r i a l

Nota Como en 10s demas casos, tambien puede acceder a la consulta SQL y modificarla 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

En 10s puntos previos nos hemos centrado en la edici6n de datos, asumiendo, por supuesto, que la estructura de las bases de datos ya se encuentra establecida. Gracias a las Visual Database Tools de Visual Studio .NET, no obstante, tambi6n tenemos la posibilidad de editar la informaci6n de esquema si estamos usando MSDE 0, en el caso de las ediciones Enterprise, de cualquier origen de datos tip0 RDBMS, incluidos Oracle y SQL Server. Podemos crear nuevas tablas, vistas y procedimientos almacenados, asi como modificar la estructura de 10s elementos existentes siempre que el origen no nos lo impida, por ejemplo porque causase una p6rdida de informaci6n.

_

~

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 secundario 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 cuadricula donde podri ir introduciendo el nombre de cada columna, su tipo de dato, longitud, 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 provisional 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 solicitando un nombre definitivo para ella. A1 igual que ocurria a1 abrir una tabla para edicicin de datos, mientras disefiamos 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: 0

Generar secuencia de comandos de carnbio:Finalizado el disefio o modificaci6n de la tabla, a1 pulsar este b o t h se generarti la secuencia de comandos SQL correspondiente. En principio dicha secuencia aparece en una ventana (vease figura 13.20) desde la que podemos guardarla en un archivo. Si lo

13. Herramientas visuales de datos

desea, puede activar la opci6n Generar automaticamente secuencia de comandos de cambio al guardar para que, sin necesidad de volver a pulsar este b o t h , se genere autom6ticamente esa secuencia de comandos cuando haya finalizado el diseiio.

I

Figura 13.18. Podemos tanto modificar la estructura de una tabla existente como crear nuevas tablas

Figura 13.19. Barra de botones especifica para el disefio de la estructura de una tabla 0

0

Establecer clave principal: A1 pulsar este b o t h se establece como clave principal la columna, o columnas, que tuviksemos seleccionada en ese momento. Esto produce, en la secuencia de comandos SQL, una restriccih de clave primaria y otra que impide la introduccih de valores nulos. Relaciones: En caso de que estemos disefiando multiples tablas, y las relaciones existentes entre ellas, este b o t h nos llevar6 a la p6gina Relaciones de la ventana de propiedades de la tabla. En ella podemos establecer la relaci6n que esta tabla tenga con otra. En la figura 13.21, por ejemplo, est6 relacionindose la tabla TABLA3,que presumiblemente va a registrar movimientos de cuentas, con la tabla TABLA1,que contiene 10s datos de cada cuenta. De esta manera se crea una clave externa.

Programacidn d e bases de datos con Visual Basic .NET

&sea

CREATE T

Q u a r k esta Eealerw de c a a n d o s de c d w en tm W

F SCOTT TABLA 1

de text02

~ W O

h

i DCUENTA CtlAR(14).

m A Q WAR(Zs), SMDO rwILER(18,2)

k ALTERTPleLE SCOTT.TABLA1 MODIFY IDCUENTA wAR(1.I) C D N W M - T A B L A l NOTNULL;

P T E R TABLE XOTT.TAELA1 Aw C C W 5 R A M K-TABLA1 PRIMARV CY Y

Figura 13.20. Secuencia de comandos de creacion de una tabla

Figura 13.21. Establecemos las relaciones entre tablas 0

Administrar indices y claves: Abre la misma ventana que se muestra en la figura 13.21, per0 con la pigina fndices o claves en primer plano. Desde ella podrin crearse nuevos indices asociados a la tabla, asi como establecer la clave principal en caso de que no la hubiesemos fijado previamente con el b o t h Establecer clave principal. No tiene mis que ir pulsando el b o t h Nuevo de la pigina fndices o claves para ir aiiadiendo indices, seleccionando 10s nombres de las columnas participantes e introduciendo el nombre que tendr6 el indice.

13. Herramientas visuales de datos

0

Administrar restricciones Check: El 6ltimo de 10s botones nos lleva a la PAgina Restricciones CHECK de la misma ventana de propiedades (vease figura 13.22), en la que podemos definir restricciones adicionales que pudieramos necesitar.

Creadas las tablas, tras cerrar las ventanas de disefio y responder afirmativamente a la pregunta de si se desean guardar 10s cambios, podemos editar su contenido como con cualquier otra tabla.

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 base 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 permite 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 entorno de Visual Studio .NET.

Prograrnacidn d e bases de datos con V i s u a l Basic .NET

El disefio de una vista se efectua a traves de 10s paneles de diagrama, cuadricula y SQL que conocimos en el punto dedicado a la edici6n de datos. La diferencia es que la sentencia SQL resultante ser6 asociada a una vista. Seleccione la vista que teniamos como ejemplo, abra el menu emergente y luego elija la opci6n DiseAar vista. Deber6 encontrarse con un entorno como el de la figura 13.23. Ya que la vista existia, aparecen las tablas que la forman, sus relaciones y selecci6n de columnas y criterios. Podemos introducir modificaciones en cualquiera de esos apartados, por ejemplo estableciendo un criterio de selecci6n de filas, y luego cerrar la vista respondiendo afirmativamente a la pregunta de si desea guardarla. Con esto habr6 modificado la vista en el servidor de datos. Usando esos mismos elementos puede crear una nueva vista. Pruebe a afiadir una vista a las bases de datos existentes para familiarizarse con 10s distintos paneles y la barra de herramientas asociada.

IY

/1

I

'iklSElEcr

WHERE

NOKBRFAS Edltorld', LIBROS LO ps Tib;lo; EDITORIALES, LIBROS EDITOMALES IDEDmORIAL = LIBROS EDITORIAL EDITOMALES

1Edlond I_

friar0

men

- hnaya Mulmmeda

Anaya Mulbmedia

nap 1-

1-

itme medial

Anaya Mulhmedla Anaya Multmmeda Anaya Muitmedia Anaya Mulbmeda Anaya Multmedla

---.ll.'

LiiKOS P c C f i

-__

-

-

--

-

--

--

[PREUO

User Interface D e q n fm Programmers s g l server 2000 Guia paceca para uwarms IBuMm 7 Prwamaoon mn Visud Clt NET Programaooncor Vlwal s b h o NET Programman con VISA B a x NET Guia p a d m para uwarlos de Visual Basc NEl tuia paceca pala usuanos de Viyld S b h o NET Programaooncon Deiphi 6 y Kyhx

- _---__

.-"A-r%h.l.L-

31 10.75

10.75 39 40 39 10,75 10,52 373

________ 'DEl-

I

I

I

--

J

---

Figura 13.23. Elementos para el diseiio de una vista

icion de procedimientos almacenados y funciones Desde el entorno de Visual Studio .NET es posible ejecutar procedimientos almacenados y funciones que residen en un RDBMS, asi como editarlos, crearlos y,

13. Herramientas visuales de datos

en el caso de SQL Server, incluso depurarlos. Si hace clic con el b o t h secundario del rat6n sobre un procedimiento almacenado, Vera aparecer un men^ emergente similar a1 de la figura 13.24. En 61 se encuentran las opciones adecuadas para ejecutarlo, editar el codigo, depurarlo o crear un nuevo procedimiento almacenado.

I7

Editar Procedmiento almacenado

i r a Procedimiento almacenado FJuevo procedimento almacenado Actualizar

Snerw s e m n a a de cwnandos de oeaam

I%

...

Propedades

Figura 13.24. Menu de opciones asociado a un procedimiento almacenado SQL Server

A1 ejecutar un procedimiento almacenado, Vera aparecer 10s resultados en el panel Resultados de Visual Studio .NET, como si hubiese ejecutado cualquier aplicaci6n. Si el procedimiento tiene parhmetros de entrada, como ocurre con uno de 10s que definimos a mod0 de ejemplo en el tercer capitulo, apareceri un pequeiio cuadro de dialog0 como el de la figura 13.25, mostrando una fila por cada parametro que se precise. No tenemos mhs que introducir el valor y pulsar el b o t h Aceptar para ejecutar el procedimiento y ver el resultado.

Las operaciones descritas en este punto son aplicables, igualmente, a las funciones, que pueden crearse, editarse y ejecutarse desde el entorno de Visual Studio .NET.

Figura 13.25. Parametros necesarios para ejecutar un procedimiento almacenado

Programacidn d e buses de dutos con Visual Basic .NET

Los procedimientos almacenados, ya Sean existentes o nuevos, se manipulan en el entorno de Visual Studio .NET en el editor de ddigo, como si de un m6dulo cualquiera se tratase. Este editor, no obstante, reconoce la sintaxis del lenguaje en el que est4 escrito el procedimiento almacenado, ofreciendo opciones especificas para ejecutarlo o disefiar aquellos bloques SQL que efectuan selecciones de datos. Observe la figura 13.26, en la que est6 edittindose el procedimiento almacenado NumTitulosEditorial de SQL Server. En la parte superior aparece el c6digo del procedimiento almacenado. Fijese en c6mo la selecci6n de datos se encuentra delimitada por una linea. Mediante el menu emergente se ha ejecutado el procedimiento, obtenihdose el resultado que aparece en la parte inferior.

Figura 13.26. Edicion de un procedimiento alrnacenado

Mediante la opci6n Diseiiar bloque SQL podri disefiar visualmente el bloque de SQL que aparece delimitado por la linea, sirvikndose para ello de 10s mismos paneles que utilizaria a1 diseiiar una vista. Si trabaja con SQL Server, como en este caso, puede establecer puntos de parada en el c6digo del procedimiento a fin de poder depurarlo, como haria en cualquier programa.

13. Herramientas visuales de datos

Si utiliza la opcion Nuevo procedimiento almacenado para crear nuevos procedimientos, observara que el esqueleto de codigo que aparece en el editor se ajusta a la sintaxis propia del RDBMS con el que estemos trabajando. Esto es asi, al menos, con SQL Server y Oracle.

Ahora que ya sabemos c6mo emplear las herramientas visuales de bases de datos 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 unica novedad es que en lugar de crearlos mediante cbdigo, como en capitulos previos, 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.

Figura 13.27. Cornponentes de la seccion Datos en el Cuadro de herramientas

Programacidn de bases de datos con Visual Basic .NET

En principio no contamos con componentes especificos para 10s proveedores Oracleclient y Odbc.Siempre que tenga dichos proveedores instalados, puede seleccionar la opci6n Personalizar cuadro de herramientas del menu emergente del Cuadro de herrarnientas, abrir la pBgina Componentes de .NET Framework y activar 10s componentes Oracle Command, Oracl eCommandBui lde r, OracleConnection y OracleDataAdapter, como se ha hecho en la figura 13.28, y / o 10s componentes Odb cCommand, Odb cCommandBui lder, Odb cConnection y Odb cDa taAdap te r. Tras cerrar el cuadro de didogo, pulsando el b o t h Aceptar, verB aparecer en el Cuadro de herramientas todos esos componentes.

UOdbcDataAdapter mOleDbCommand OleDbCommandBuilder ~OleobComecbon mOleDboataAdapter OpenFileDialog OOradeCommand DradeCommandBuilder mOradeConnecbon OradeDataAdapter

7 I/

I/

-

-

Microsoft Data Odbc System Data OleDb System Data OleDb System Data OleDb

System Data OleDb System hindows Foimr System Data OradeClient

System Data OradeClient System Data OradeClient System Data OradeClient

__

Miaosoft.Data.Odbc (1.0.3300.G) Svrtem.Data (1.0.3M0.0) System.Data (1.0.3M0.0) System.Data (1.0.3M0.0) Svrtem.Data (1.0.3M0.0) System.Wmdows.Fams (1.0.330.0) System.Data.OradeClient (1.0.3330.0) System.Data.OradeCbent (l.G.3M0.0) System .Data .OradeClient (1 .0 ,3300 .0) System .Data .OradeClient (1 .0 ,3330 .0)

. .--. .

. .

-

. ...I

I

-

I

.

fY’

. -.. .

!.>I

1

II

Figura 13.28. Seleccion de 10s componentes correspondientes a 10s demas proveedores

Teniendo todos 10s componentes dispuestos en el Cuadro de herrarnientas, en 10s puntos siguientes vamos a usarlos para establecer una conexibn, definir un comando, preparar un adaptador de datos y generar un conjunto de datos, todo ello sin necesidad de escribir codigo alguno.

re Dependiendo del proveedor que desee emplear, haga doble clic sobre el componente 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 ventana 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

lista que, a1 desplegarse, muestra la lista de conexiones que hay predefinidas en el Explorador de servidores, pudiendo seleccionar directamente cualquiera de ellas. Si no nos interesa ninguna de ellas, no tenemos m i s que seleccionar la opci6n Nueva conexion para abrir el cuadro de diilogo Propiedades de vinculo de datos y definir las propiedades de la conexi6n.

El componente Sqlconnection se comporta practicamente de forma identica a OleDbConnection,de tal forma que la propiedad connectionstring tambien muestra la lista desplegable con la opcion Nueva conexion. Los compOnenteS OracleConnection y OdbcConnection, por el contrario, no disponen de esa lista ni asistente alguno, por lo que la cadena de conexion debe escribirse directamente como valor de la propiedad Connectionstring. En la figura 13.29 puede ver c6mo se ha insertado un OleDbConnection en una aplicaci6n Windows y c6mo, abriendo la lista adjunta a la propiedad Connectionst ring, se elige una de las conexiones predeterminadas, concretamente la de acceso a1 libro Microsoft Excel. Si nos interesa, podemos cambiar el nombre del componente por otro m i s adecuado. En este ejemplo mantendremos 10s nombres por defect0 que tienen 10s componentes a1 ser insertados. Tras la inserci6n del componente de conexibn, y asignaci6n de un valor apropiado a Connectionstring, para abrir la conexidn usariamos el componente como si de una variable previamente declarada se tratase, es decir, como hariamos con cualquier otro componente en Visual Basic .NET. La sentencia siguiente, por tanto, usaria el componente insertado en la figura 13.29 para abrir la conexi6n con el libro de Microsoft Excel. 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 automaticamente la variable, y las propiedades del comando se establecen visualmente. Nos encontraremos, no obstante, con exactamente las mismas propiedades que ya conocimos 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

Figura 13.29. Seleccion de la cadena de conexion

Connection: Despliegue la lista adjunta y, del nodo Existente, elija luego la conexi6n OleDbConnectionl. De esta manera ya tiene asociado el comando con la conexi6n.

Si no tiene un componente de conexion, porque no lo haya insertado previamente, puede usar la opcion Nueva de la propiedad Connection para definirla en ese mismo momento, generandose automaticamente el componente OleDbConnection. 0

CommandType: Esta propiedad tambikn tiene asociada una lista de opciones, de la que puede elegir si el comando recuperar6 directamente una tabla, contiene una sentencia SQL o el nombre de un procedimiento almacenado. Mantenemos el valor Text que aparece por defecto, indicando que el comando tendri asociada una sentencia SQL.

13. Herramientas visuales de datos

0

CommandText: A1 seleccionar esta propiedad veri aparecer un b o t h , en el extremo derecho, con tres puntos suspensivos. Pulselo para abrir la ventana Generador de consultas (vease figura 13.30) y, usando 10s paneles que ya conoci6 en puntos previos, diseiiar visualmente la selecci6n de datos.

> A 1

Y

> nulo Aubr Preoo

V

>

Figura 13.30. Generador visual de consultas

La ventana Generadorde consultas no aparece, en este caso, como un diseiiador de Visual Studio .NET sin0 como una ventana independiente. Lbgicamente, podemos definir tantos comandos como necesitemos para efectuar nuestro trabajo. En este caso nos quedaremos s610 con el comando que puede verse en la figura 13.30, introducido en el componente OleDbCommandl.

En este momento, tras definir el comando, podriamos ponernos a escribir c6di-

go para, mediante el metodo ExecuteReader ( ) , obtener un OleDbDataReader y recuperar datos. Nuestro objetivo, sin embargo, es recuperar dichos datos en un DataSet con el fin de vincularlo con un D a t a G r i d , asi que el paso siguiente serti definir el adaptador de datos que, partiendo del comando, llenarti el DataSet. Haga doble clic sobre el elemento OleDbDataAdapter, en el Cuadro de herramientas, para insertar un objeto de esa clase en la aplicacih. Se pondr6 en marcha

Programacidn de bases de datos con Visual Basic .NET

un asistente de configuracih que, en este caso, vamos a cerrar pulsando el boton Cancelar. Asi accederemos directamente a las propiedades del adaptador. Si observa la ventana Propiedades ver6 algunas como SelectCommand, TableMappings o MissingSchemaAction, que ya conoce de capitulos previos. Despliegue la lista adjunta a SelectCommand y elija del nodo Existente el unico elemento disponible. Con esto ya ha asociado el adaptador de datos con el comando definido antes. Seleccione la propiedad TableMappings y luego pulse el b o t h que aparece tras (Coleccion), accediendo a la ventana mostrada en la figura 13.31. En ella asociaremos la unica tabla de entrada, procedente de la sentencia SQL definida en el comando, con una tabla que existir6 en el DataSet a la que llamaremos Libros. Pulsamos el b o t h Aceptar y damos por acabada la configuracih del adaptador.

Figura 13.31. Asociaciones entre tablas de origen y tablas del conjunto de datos

En el mismo cuadro de dialogo Asignaciones de tablas puede tambien establecer una correspondencia entre las columnas del origen de datos y las que existiran en el conjunto, si es que este cuenta con una estructura predefinida.

s El penultimo paso, en cuanto a tareas de diseiio se refiere en este simple ejemplo, 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

adaptador de datos, se pondrfi en marcha un asistente que cerraremos pulsando el b o t h Cancelar. De esta forma tenemos un conjunto de datos simple y vacio, como 10s que utilizfibamos en 10s capitulos previos. La ventana Propiedades muestra todas las propiedades del DataSet,resultando especialmente interesantes En forceCons t raint s , Re1 ati ons y Tab1e s, que ya conocemos. Puesto que trabajaremos sobre una sola tabla, no van a existir relaciones, pero abriendo la colecci6n Relations tendremos acceso a un cuadro de difilogo desde el cual pueden ir definiendose esas propiedades de manera visual. Si vamos a tener una tabla, asi que seleccionamos la propiedad Tables y abrimos el correspondiente editor de esta colecci6n. En principio no aparece elemento alguno, asi que pulsamos el b o t h Agregar para insertar una nueva tabla. A la derecha, como se ve en la figura 13.32, aparecen todas sus propiedades. S610 vamos a modificar TableName, asignfindole el mismo nombre que dimos a la tabla en el adaptador de datos, es decir, Libros.

Figura 13.32. Edicion de 10s elementos de la coleccion T a b l e s de un D a t a S e t

Observe que, a diferencia del resto de componentes, el DataSet no se enlaza directamente con el adaptador de datos o cualquier otro componente. Sera mediante codigo como lo llenemos con datos.

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

del Cuadro de herramientas y tome un componente DataGrid, insertiindolo en el formulario. Modifique la propiedad Dock para que ocupe todo el espacio disponible. Despliegue la lista adjunta a la propiedad Datasource y seleccione el elemento Data S et 1,vinculando asi la rejilla de datos con el conjunto de datos. Dado que este puede contar con mLiltiples tablas, usaremos la propiedad DataMember para seleccionar la que deseemos. En este caso s610 hay una disponible, asi que la elegimos. La interfaz, finalizada, quedaria como se aprecia en la figura 13.33. Observe en la parte inferior del 6rea central 10s componentes que se han ido insertando en 10s pasos previos.

________

0Wndow

~

-

A

E

Tw, Left

0Wndow

I Amworkspace

8 M

FixedD [z1 AcbveCapbon AcbveCapbanText

I

Llsto

Figura 13.33. Aspect0 del forrnulario con el DataGrid en su interior

Si ejecut6semos el programa tal y como est6 en este momento, veriamos que la rejilla de datos permanece vacia. Es 16gic0, puesto que la hemos vinculado con un DataSet que est6 vacio y, ademis, en ningtin momento hemos vinculado 4ste con el adaptador de datos. Para hacerlo, abrimos la ventana de c6digo y, en el evento Load del formulario, insertamos la sentencia siguiente: OleDbDataAdapterl.Fill(DataSet1)

No es mucho codigo, especialmente si lo comparamos con algunos de 10s ejemplos de capitulos previos y el resultado obtenido que, en este caso, seria el de la figura 13.34. Una rejilla en la que podemos navegar por 10s datos.

Frarcisco Cbarte M esvs L L w e Frarcisco Charte

IntrodLccior a la programion Marual a.anzado Grcel :W2 F,lawal &I microrrocesador 33386 Programaacn C G Oelph ~ 6, K , h P r o g a r x i o r c w t/lsbal b s i c NET

FraTx-iscu'Itsrte Farcisco Charte Frapcisco Charte Ckris H Pappas&'Allialr H Murra, Ill Frarcisco Charte Frarcisco Chide Frsrcisco Chide

12 52

40

sLal Studio NET

Figura 13.34. Ventana con la rejilla de datos

No cabe duda, usando 10s componentes de conexi6n a datos como hemos hecho en 10s puntos previos, insertandolos en un disefiador y personalizandolos mediante el us0 de la ventana Propiedades, ahorramos una cantidad importante de trabajo 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 muestra el resultado de una consulta SQL, sin necesidad de recorrer filas, acceder a columnas y acciones similares mediante c6digo. No obstante, el trabajo puede simplificarse atin mAs mediante la creaci6n automitica de parte de 10s componentes que, en 10s anteriores puntos, hemos ido insertando 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 insert6 en el ejemplo previo.

Los adaptadores de datos cuentan con un asistente que facilita su configuracidn, asistente que anteriormente cerramos sin usarlo. Ahora, partiendo de un proyecto en el que tan s610 tenemos un formulario vacio, vamos a hacer doble clic sobre el

elemento OleDbDataAdapter del Cuadro de herramientas para poner ese asistente en marcha. La primera ventana que aparece es simplemente indicativa, bastando con pulsar el b o t h Siguiente > para ir a1 siguiente paso. En 61 deberemos seleccionar la conexi6n asociada a1 adaptador, ya sea eligiendo una de las existentes, tal y como se hace en la figura 13.35, o bien pulsando el b o t h Nueva conexidn para definir una nueva. En este caso nos encontraremos con el cuadro de di6logo que ya conocemos. Para seguir este ejemplo vamos a optar por la conexi6n Libros . d b o del servidor en el cual se tenga SQL Server en funcionamiento, en mi caso particular 1NSPIRON.Libros.dbo.

Figura 13.35. Seleccionamos la conexion que utilizara el adaptador de datos

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 opciones 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 selecci6n 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 almacenado para obtener 10s datos, otro para actualizar, otro para insertar y otro para borrar, utiliz6ndolos cuando sea necesario. De esta forma las sentencias SQL ya se encontrarin compiladas en el RDBMS y el rendimiento ser6 superior.

13. Herramientas visuales d e datos

Usar procedimientos almacenados existentes: En caso de que ya hubiesemos empleado la opci6n anterior en otro adaptador, en el RDBMS existirAn 10s procedimientos almacenados apropiados para efectuar las tareas de edicibn, por lo que usariamos esta opci6n con el fin de aprovecharlos en lugar de generar otros nuevos.

Figura 13.36. Seleccionamos el mecanismo que se utilizara para la actualizacion de 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 sencilla como la de la figura 13.37, puede pulsar el b o t h Generador de consultas para 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 izquierda, abrir6 entonces la ventana Opciones d e generacion SQL avanzadas (vease figura 13.38). En ella aparecen tres opciones inicialmente activadas. La primera provoca que el asistente genere, aparte del comando de seleccibn, comandos adicionales para la insercih, actualizacidn y eliminacih. Con la segunda se conseguir5 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 actualizaci6n 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...

Figura 13.37. lntroducimos la sentencia SQL de seleccion de datos

Figura 13.38. Opciones avanzadas de generacion de sentencias SQL

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 pulsaci6n 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 asistente encontrara las siguientes declaraciones justo antes del mktodo 1 nit i a 1i zeComponent ( ) :

Friend WithEvents O l e D b S e l e c t C o m m a n d l System.Data.01eDb.OleDbCornrnand Friend Wi thEvents 01 e Db I n s e r t C o m m a nd 1 System.Data.01eDb.01eDbCommand Friend WithEvents OleDbUpdateCornrnandl System. D a t a . Ole Db. 0 1 e D b C o m m a n d Friend WithEvents O l e D b D e l e t e C o m m a n d l 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

As As As As

~

~

~

~

Existe, por tanto, un OleDbCommand para s e l e c c h , otro para insercion, un tercero para actualizaci6n y uno mds para eliminaci6n de filas. Busque m6s adelante la asignaci6n a la propiedad CommandText de cada uno de 10s OleDbCommand y examine las sentencias SQL, especialmente las utilizadas para actualizar y eliminar filas existentes.

. " Puede cambiar la configuracion de un adaptador de datos en cualquier momento, 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 opcion homonima del menu emergente del OleDbAdapter.

Acabamos de configurar nuestro adaptador de datos que, una vez lo conectemos con un DataSet,suponemos nos facilitar6 la visualizaci6n y edici6n de todas las filas de la tabla Libros. Esta suposicidn puede convertirse en seguridad de forma muy sencilla: seleccionando la opci6n Vista previa de datos del menu emergente asociado a1 adaptador. En principio se encontrard con un cuadro de didlogo en el que aparece el nombre del adaptador de datos, en la parte superior izquierda, y varias Areas vacias en el resto de la ventana. Pulse el b o t h Llenar conjunto de datos. De inmediato Vera c6mo aparece el conjunto de filas resultante, asi como el nombre de las tablas de datos, en este caso s610 una, y el tamafio global del conjunto de datos. La figura 13.39 muestra la vista previa del adaptador definido en el punto previo. Puede cerrar la ventana, volviendo de nuevo a1 entorno de disefio a fin de proceder a la creaci6n del conjunto de datos.

Partiendo del adaptador de datos, que ya tenemos definido y comprobado, generar el Data S e t es un juego de nifios. Bastard con abrir el menu emergente del

13. Herramientas visuales de datos

Figura 13.40. Opciones de generacion del conjunto de datos

Aunque en principio parece que tan s610 se ha aiiadido el esquema XSD, si pulsa 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 contenido. 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 DataC 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 facilitar 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

en la que quiere accederse a la columna E d i t o r i a l de la primera fila de la tabla L i b r o s , puedan simplificarse asi: DataSetll.Libros(O).Editorial

=

3

No es necesario emplear las colecciones T a b l e s , R o w s o Columns,ya que la clase Data S e t 1 cuenta con propiedades que, como L i b r os, ya acceden a esos elementos por nosotros. El conjunto de datos con tip0 nos ofrece, ademds, la integraci6n con la tecnologia IntelliSense del editor de cbdigo, como puede apreciarse en la figura 13.41. En la lista de miembros aparecen 10s nombres de las tablas y de las columnas del conjunto de datos, lo cual hace mucho mas simple nuestro trabajo.

Programacidn de bases de datos con Visual Basic .NET

Figura 13.41. Miernbros del conjunto de datos con tip0

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.

I

....

.-

_

i

_

~

-"_

".-.l_l___.~.-^".-ll_---~..~-~~

_____l___~~~.l__ ___-_^_

En 10s dos ultimos puntos, utilizando el asistente de configuracion de adaptadores de datos y el generador de conjuntos de datos, ha efectuado el mismo proceso y creado 10s mismos componentes que en 10s apartados anteriores, en mucho menos tiempo y con menos operaciones manuales. iEs posible hacerlo con aun menos trabajo? Pues si, es posible. Los elementos que aparecen en el Explorador de servidores pueden arrastrarse hasta un diseiiador, y las tablas, vistas y procedimientos almacenados no son una excepcih. ~ Q u ocurre e si toma, por ejemplo, la tabla Editoriales desde la base

13. Herramientas uisuales de datos

de datos SQL Server y la suelta sobre el formulario Windows? HAgalo y compruebe como se configura automAticamente el adaptador de datos y la conexi6n. Lo unico que tiene que hacer es abrir el menu emergente del adaptador y elegir la opcion Generar conjunto de datos. Ya tiene todo el trabajo anterior hecho en dos operaciones de raton. En lugar de una tabla puede arrastrar una vista, obteniendo el mismo resultado, e incluso un procedimiento almacenado, caso en el que se crea un SqlCommand, o equivalente, que facilita su ejecuci6n.

Tambien puede arrastrar hasta un diseiiador cualquiera de las conexiones que tenga predefinidas en la rama Conexiones de datos del Explorador de servidores, creando y configurando automaticamente un objeto OleDbConnection.

. .~....._.I....__.....

..~.....I__......__' . -.....~__.I_.... _. .

..

....

...

._. .

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 depuracion 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 adaptadores, comandos y conjuntos de datos, en el capitulo proximo veremos c6mo conectar 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 ejemplos de 10s capitulos de la segunda parte del libro, no es precisamente el mecanismo 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 ventanas, ejecut6ndose por ejemplo sobre Windows, o bien las interfaces Web, accesibles 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 transmitir10s a1 origen de datos, lo cierto es que la mayor parte de ese proceso puede automatizarse 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, tabla 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 conjunto 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 clasificarse, en cuanto a su vinculaci6n a datos, en las tres categorias siguientes: 0

0

0

Controles que tan solo precisan el contenido de una columna de una cierta fila, por ejemplo 10s TextBox y similares. Controles capaces de mostrar el valor que tiene una cierta columna en multiples fhas, por ejemplo un ListBox o ComboBox. Controles tip0 cuadricula en 10s que aparecen multiples filas con multiples columnas, como el DataGrid que usibamos en uno de 10s ejemplos del capitulo previo.

La conexion de cada una de estas categorias de control con el origen de datos se efectua, como va a verse en 10s puntos siguientes, de forma distinta.

La mayoria de 10s componentes que estamos habituados a utilizar en el disefio de interfaces de usuario, tanto Windows como Web con ASP.NET, pueden vincular sus propiedades con un origen de datos, por regla general con una cierta columna de un conjunto de datos, vista o tabla. Los controles Windows disponen de una propiedad, llamada DataBindings, que almacena la colecci6n de vinculaciones o enlaces entre propiedades del control y una fuente de datos. Los controles ASE'.NET emplean un sistema distinto, per0 igualmente sencillo. Los objetos de la colecci6n a la que apunta DataBindings son de clase Binding, estableciendo cada uno de ellos un enlace para una propiedad del control. Esto significa, por tanto, que es posible definir multiples vinculos con diferentes propiedades de un mismo control, a pesar de que no es lo m i s habitual. Cada uno de esos objetos mantiene tres datos distintos para hacer posible el enlace, datos que es precis0 facilitar a1 constructor en el momento de la creation. Son kstos: 0

0

Nombre de la propiedad: Los objetos Binding se aiiaden a la coleccion DataBindings de un cierto control, por lo que tan s610 precisan conocer, en cuanto a1 control de destino se refiere, el nombre de la propiedad que va a enlazarse. Origen de datos: El objeto del que va a leerse la informacidn, normalmente un DataSet, DataTable o DataView aunque, como se apunt6 anteriormente, tambikn podria ser una lista o un arreglo.

Programacidn de bases de datos con Visual Basic .NET

Miembros de datos: El origen de datos generalmente contendr6 multiples columnas, y 10s objetos Binding estan pensados para vinculos simples, con una sola columna cuyo nombre hay que facilitar como miembro de datos. 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 Birdirlg ("Text", I)sLibrr,rl . L i b r o ~ ,"Titiilo") ) ~

En realidad, usando el diseiiador de formularios de Visual Studio .NET raramente tendremos que escribir sentencias de este tip0 ya que, como otras, la propiedad DataBindings puede ser editada en la ventana Propiedades. Esta propiedad se encuentra en el apartado Datos, si tenemos las propiedades agrupadas por categorias, o bien como una de las primeras propiedades, si usamos el orden alfabktico. A1 desplegar DataBindings nos encontramos con tres elementos, siendo dos de ellos las propiedades Text y Tag.Son las que se suelen vincular con datos. Para conseguir el mismo efecto que la sentencia anterior, por tanto, seleccionariamos el control TextBoxl y hariamos lo que puede verse en la figura 14.1, desplegar la lista adjunta a la propiedad Text y seleccionar la columna de origen. En caso de que la propiedad que deseemos vincular no sea una de las que nos ofrece por defect0 la propiedad DataBindings, podemos pulsar el b o t h asociado a la entrada (Avanzado) para abrir la ventana Enlace de datos avanzado (vkase figura 14.2). En ella se enumeran todas las propiedades del control que pueden ser vinculadas, pudiendo seleccionar distintos origenes para cada una de ellas. Los controles ASP.NET, a pesar de que en la fase de disefio parecen idknticos a sus equivalentes para Windows, cuentan con un mecanismo de enlace a datos diferente. Si inserta un TextBox en un formulario Web y, en la ventana Propiedades, accede a su propiedad DataBindings, se encontrar6 con una ventana como la que muestra la figura 14.3. Su funcionamiento es similar a lo explicado en el parrafo anterior, pudiendo seleccionar para cada propiedad una vinculacih de acceso a datos. Si tras establecer el vinculo examina el c6digo HTML del documento, sin embargo, ver6 queTextBoxl en realidad no dispone de la propiedad DataBindings, sin0 que se ha asignado a su propiedad Text lo que se conoce como una expresidn de vinculacidn. En este caso dicha expresi6n es la siguiente: T ex t = ' < % # Da t a B i ride r . Eva 1 ( Ds L i b r o s 1 , " T a b l e s [ L i b r o s ] .Defaultview. [ 01 . T i tulo") % >

14. Componentes con vinculacidn a datos

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 Rindow FixedD True Normal

0

(ningunoi IBearn ilD"e

True Microsoii Sans Serif, 3 25pt

NindowText True

EiKrnboi

Figura 14.1. Edicion visual de la propiedad DataBindings para vincular la propiedad Text de un TextBox

En lugar de utilizar DataBinder, que es lo que hace por defect0 el editor de la propiedad Data Bindings,podemos introducir una expresi6n de vinculacidn personalizada haciendo referencia directa a1 conjunto de datos que hayamos creado previamente. En la figura 14.4, por ejemplo, puede observar c6mo se ha activado la opci6n Expresion d e enlace personalizada e introducido la expresion dsLibrosl Libros ( 0). Titulo, vinculando asi el TextBox con el titulo de la primera fila de la tabla de libros. Independientemente del metodo que empleemos para establecer la vinculacion, para que 6sta sea efectiva es necesario siempre llamar a1 metodo DataBind ( ) , que se encarga de resolver las expresiones una vez que el componente de origen ya dispone de 10s datos a utilizar. Si son multiples 10s controles vinculados, en lugar de llamar a1 metodo DataBind ( ) de cada uno de ellos, que seria valido per0 rei-

.

Programacidn de bases de datos con Visual Basic .NET

terativo, puede invocarse a1 mismo metodo de la ptigina, encargkdose 6sta de todos 10s controles hijo que contiene.

(Nmsuno) (Nmguno) [Nmguno) (Nwno) Wmguno) @nguno:

pimguno) (Nmguno) (Niguno)

(Nmguno) WrnSUnQ! (Nmguno)

(Nmguno) (Nmguno) (Nmguno) iblinguno) DsLibrosl Libios Tltulo

(Nmguno) “mguno) INnauno)

Figura 14.2. Vinculacion de multiples propiedades del mismo control

....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

+

Columns I CssClasr Enabled Font

+

0 Editorial

+

0 IDLibro

+ +

U Preoo Y

Figura 14.3. Ventana de la propiedad D a t a B i n d i n g s correspondiente a un T e x t B o x de ASP.NET

14. Cornponentes con vinculacidn a datos

la propiedad que &a edazar A cmti-lm, utilice el erdac.? smple para enlaza onmelementadedatmy estaMecerelfmtcoutiliceelenlace perwrnltzadoparaescntdr

s+(eccl;re ~a

m e s t o r de enlace

Figura 14.4. lntroducimos una expresion personalizada de vinculacion a datos

Son varios 10s componentes capaces de mostrar el valor que una cierta columna tiene en multiples filas, siendo 10s mas habituales ListBox y ComboBox. Cualquiera 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 elementos 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 programa 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 propiedades 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 mostrar6 en la lista. ValueMember: Indica la columna cuyo contenido se obtendrfi como valor asociado a cada uno de 10s elementos de la lista.

Suponiendo que deseasemos mostrar en un control ListBox 10s titulos de todos 10s libros y que, a1 elegir cualquiera de ellos, se obtuviese el identificador del seleccionado, asignariamos entonces el valor Titulo a DisplayMember e I D L i -

Programacidn de bases de datos con Visual Basic .NET

bro a ValueMember, mientras que Datasource podria ser DsLibrosl. Libros, suponiendo que tenemos un DataSet llamado DsLibros 1 conteniendo la tabla Libros. En caso de que usemos 10s controles Web equivalentes, las propiedades a utilizar serdn las cuatro siguientes: 0

0

Datasource: La referencia a1 conjunto de datos u objeto que contiene la information. DataMember: En caso de que el objeto anterior sea un DataSet, con esta propiedad seleccionariamos una de las tablas disponibles. DataTextField: Equivalente a DisplayMember, conteniendo el nombre de la columna que se mostrara en el control.

0

DataValueField: Equivalente a ValueMember, indicando la columna de donde se tomar6 el valor a asociar a cada elemento.

Puede hacer una prueba simple insertando un ListBox en una p6gina Web ASP.NET, junto con un TextBox, y enlazando la lista con la columna Titulo de la tabla Libros. D6 el valor True a la propiedad AutoPostBack del ListBox y, tras hacer doble clic sobre 61, introduzca la siguiente sentencia: TcxtBoxl.Text

=

ListBoxl.SelectedItern.Va1ue

A1 ejecutar el programa deberia obtener un resultado similar a1 de la figura 14.5, donde ve cdmo a1 seleccionar un titulo su identificador aparece en la caja de texto. Esto es asi porque hemos dado el valor IDLibro a la propiedad DataValueField.

_________

~

-

rarnacion con Visual Studio NET :*I

/Guia practica para usuarios de Visual Basic NET 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

i

7

Figura 14.5. Vinculacion de una lista ASP.NET con 10s valores de una columna

14. Componentes con vinculacion a datos

Este mismo ejemplo puede aplicarse con un L i s t B o x en un formulario Windows, tan solo tiene que cambiar las propiedades de vinculacion de la lista, manteniendo el resto igual.

La tercera categoria de componentes estd compuesta exclusivamente por el control D a t a G r i d que, a diferencia de 10s anteriores, tiene la capacidad de mostrar multiples filas y columnas, pudiendo facilitar el acceso a tablas completas de information. Estos controles, por tanto, no se enlazan con una columna en particular, sino con una vista o una tabla completa. Independientemente de que usemos el D a t a G r i d de formularios Windows o formularios Web, las dos propiedades de enlaces a emplear son las mismas: D a t a S o u r c e y D a t a M e m b e r . La primera hard referencia a1 origen de datos y, en caso de que &te sea un D a t a S e t , la segunda seleccionar6 entonces una de sus tablas o vistas. Aunque el comportamiento de ambos controles D a t a G r i d difiere bastante, visualmente hablando, como se aprecia en las figuras 14.6 y 14.7, son muy similares, mostrando, como es logico, la misma informacion a1 vincularse a1 mismo origen de datos.

ISBN

&tor

Mtorial

Precio

3,

PI Spnlik,

10-5

Frarcisco Ctarte Frarcisco Ctarte Francisco Charte Fraruaco Charle-orix Seiiaro Francisco Charte Frarcieco Charte Frarcisco Ctane Francisco Charte

1

1:.

1

30

1 1 1

1%

1 1

10.52

k

39 10 7 :

3T.26

1352

Francisco Charte

1 1

Frarciscc CbarteM ,esm L w u s

1

Frarcisco Charte Francisco Cbarte

1 1

24 9

i

43

Frar=isco

Ctarte

Ill

21 34

lC5i IC 52

Figura 14.6. El control D a t a G r i d en un formulario Windows

El D a t a G r i d de ASF'.NET cuenta, adem&, con la propiedad D a t a K e y F i e l d , a la que podemos asignar el nombre de la columna que actiia como clave de la tabla o vista a fin de identificar de manera inequivoca cada fila de datos.

Programacidn de bases de datos con Visual Basic .NET

Figura 14.7. El control D a t a G r i d en un formulario Web

Mientras que el DataGrid de Windows tiene capacidades de navegacion y edicion intrinsecas, desde el momento en que se inserta en un formulario, el equivalente para formularios Web se comporta como una tabla HTML estatica, aunque es posible personalizarlo para incluir enlaces y botones que hagan posible la manipulacion de la informacion.

Ya sabemos c6mo enlazar cualquier componente Windows con un origen de datos, usando para ello la propiedad DataBindings, DataSource y DataMember, se&n 10s casos. Los controles que se vinculan con una sola columna, mediante DataBindings, no tienen nocion de la fila en la que se encuentran en el conjunto de datos, puesto que s610 conocen el valor de una columna en una determinada fila. Es el propio formulario el encargado de crear 10s elementos necesarios para asegurar la sincronizacih entre 10s distintos controles que puedan estar vinculados con datos, impidiendo que cada uno de ellos muestre el valor de una columna en filas distintas. Todos 10s formularios Windows cuentan con un objeto Bindingcontext, a1 que podemos acceder mediante la propiedad del mismo nombre, cuya finalidad es

14. Cornponentes con vinculacidn a datos

mantener una lista de objetos, uno por cada origen de datos que exista, que se encargarin 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 Propert yManager. La clase PropertyManager se usa para mantener la asociaci6n entre la propiedad 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. Siempre que el origen sea un DataTable, DataView o similar, el objeto encargado de mantener la asociaci6n seri un CurrencyManager.

El ObjetOBindingContext mantiene una lista de IOSBindingManagerBase, o derivados, existentes en el formulario, mientras que cada BindingManagerBase controla todos 10s objetos Binding de un mismo origen de datos.

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 datos, a las que puede acceder como si de un arreglo se tratase. No existe una propiedad 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 funcionalidad, lo que hacen 10s formularios Windows es crear un CurrencyManager para cada origen que mantiene una lista de datos, como 10s mencionados DataTable 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 CurrencyManager 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" )

Con esta expresi6n obtendriamos el CurrencyManager asociado con la tabla Libros del DataSet llamado DsLibrosl. LPor qu6 nos interesa obtener dicho objeto? Principalmente porque es 61 quien mantiene la posicion actual en la lista de

Programacidn de bases de datos con Visual Basic .NET

datos, contando con propiedades que nos permiten conocer y modificar dicha POsicion. La mayor parte de 10s miembros de esta clase son heredados de BindingManagerBase, 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 numero 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 conjunto de datos.

,

. .-..._(^._.-.....__I.--.. _^__I I.-.-., . x _

....-

_.___^__I__x.”

____^._ .__. ll_ll

~

_ _ _ ~ _ ^ _

Todos 10s derivados de BindingManagerBase disponen de 10s tres mktodos Refresh ( ) , SuspendBinding ( ) y ResumeBinding ( ) , con 10s cuales podemos establecer un cierto control sobre la vinculacion, y con 10s eventos CurrentChanged y PositionChanged. Cada clase derivada facilita una implementation especifica de estos miembros. El mktodo Refresh ( ) provoca la actualization de todos 10s controles enlazados con el origen a1 que representa el objeto BindingManagerBase, mientras que SuspendBinding ( ) y ResumeBinding ( ) desactivan y reactivan la vinculacion. Esto tiene sentido cuando van a efectuarse tareas de edicion sobre 10s datos que pudieran provocar una violation de las restricciones definidas en el origen, impidiendo a1 usuario trabajar de forma c6moda. A1 suspender la vinculacion 10s contenidos de 10s controles pueden modificarse sin limitaciones, efectudndose las comprobaciones en el momento en que el vinculo vuelva a establecerse. En cuanto a 10s eventos Currentchanged y PositionChanged, se producen cuando uno de 10s valores vinculados ha cambiado, mientras que el segundo notifica una modificacion de la propiedad Position.

La propiedad DataBindings que se citaba en un punto previo, a1 enlazar un TextBox con una columna de una tabla, estfi definida en la clase Control de System.Windows . Forms. Esto significa que es una propiedad heredada por todos 10s controles Windows y que, por tanto, podemos virtualmente vincular cualquier propiedad de cualquier control con una columna de un origen de datos. Existe, no obstante, un conjunto de controles que, por su naturaleza, se prestan m6s a la vinculacion. Algunos de ellos son el propio TextBox, ya usado previamente; todos 10s derivados de ButtonBase, tales como CheckBox, RadioButton y Button;10s controles PictureBox,para la visualization de imigenes, TrackBar y ScrollBaroDateTimePicker.

14. Cornponentes con vinculacidn a datos

Controles como ListBox, ComboBox y DataGrid tambien cuentan con la propiedad DataBindings, a1 fin y a1 cab0 son clases derivadas de Control, per0 cuentan con propiedades m6s especificas ya explicadas en 10s apartados del primer punto de este capitulo.

S La vinculacion a datos de las aplicaciones Web es muy distinta a la de las aplicaciones Windows, a1 ejecutarse en un entorno que, por naturaleza, es desconectado, es decir, 10s clientes no mantienen una conexi6n continua con el servidor. Los formularios ASI'.NET no disponen de la propiedad Bindingcontext ni 10s objetos derivados de BindingManagerBase, y 10s controles no facilitan la navegac i h , edici6n y actualizaci6n directa de 10s datos como si lo hacen en 10s formularios Windows. En muchas ocasiones la vinculaci6n a datos en una pdgina Web se emplea para mostrar informaci6n s610 de lectura, por ejemplo generando un informe. En otros, por el contrario, si es precisa la edicibn, para lo cual ser6 necesario controlar parte de las acciones mediante c6digo.

,

. ,,

. .'

. .. .

. . .' '.

..

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 necesaria para que 10s obtenga e instale. A cambio, en ASI'.NET existen m6s componentes capaces de presentar una lista de datos que en 10s formularios Windows. Ademis del conocido DataGrid y el control ListBox,tambikn tenemos a nuestra disposici6n 10s controles CheckBoxList, RadioButtonList, DataList y Repeater, siendo estos dos dtimos especialmente interesantes. Con Da taLis t es posible crear listas de datos basadas en una plantilla de apariencia definida por nosotros, mientras que Repeater es un contenedor en el que es posible insertar otros controles que serdn repetidos por la piigina Web. Tanto DataList como Repeater se basan en el us0 de plantillas que hay que definir directamente en el m6dulo HTML, con etiquetas tales como 0 .

~

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

tos de ejemplo, per0 sin necesitar capacidades de edicibn, inserci6n ni borrado, lo mas apropiado es usar un vinculo s610 de lectura mediante un DataReader. Los vinculos s610 de lectura emplean menos recursos, ya que un DataReader abre la conexicin y recupera 10s datos mediante un cursor unidireccional y s610 de lectura, sin crear estructuras en memoria como si hace un Data S et. Suponga que quiere mostrar en una p6gina Web una tabla con una lista de 10s titulos existentes en nuestra base de datos, utilizando para ello un componente DataList y un lector de datos. Los pasos, bbsicamente, serian 10s siguientes: Definicidn de la conexi6n y el comando para recuperar la columna Titulo de la tabla Libros. 0

Inserci6n en la pagina ASI'.NET de un componente DataList, seleccionando alguno de 10s estilos predefinidos para 41. Edici6n de la plantilla correspondiente a1 cuerpo, insertando en dl un componente que se enlazaria con la cohmna Titulo. Codificacibn, en el evento Load, de la apertura de la conexi6n y obtenci6n del DataReader, asignandolo a la propiedad Datasource del DataList.

En la figura 14.8 puede ver c6mo se ha insertado un control Label en el ItemTemplate del componente DataList, y c6mo se utiliza la propiedad DataBindings de la etiqueta de texto para vincularla con la columna Titulo. Se asume, por supuesto, que hemos insertado y configurado la conexi6n y el comando. A continuacicjn, tras hacer doble clic sobre el fondo de la pdgina, introduciriamos el c6digo siguiente: sq Da DataBind ( )

'

SylConnectionl. C use

( )

Con61 enlazamos el SqlDataReader devuelto por el mdtodo ExecuteReader ( ) con el control DataList. Este lee todos 10s titulos y genera una tabla como la que puede verse en la figura 14.9. No hemos necesitado un adaptador de datos, generar un DataSet ni nada parecido, realizando el trabajo de manera mas eficiente y con menor us0 de recursos.

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 vinculaci6n 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 dab5 y establecer el forrnato o &re el enlace persoMflzado para e s a w ma eqxeu6n

elernento de

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 : DataBinder Eval(Contamer DataItern, "TlbAo")

A

Figura 14.8. DiseAo de la plantilla para el cuerpo del DataList

La mala noticia es que 10s formularios Web no mantienen objetos equivalentes a 10s CurrencyManager o Bindingcontext de 10s formularios Windows, por lo que el mecanismo para mantener la posici6n actual y para sincronizar 10s controles vinculados queda completamente en nuestras manos. La buena noticia es que codificar esa funcionalidad no resulta excesivamente complejo. Lo primer0 que necesitamos es saber cuiintas filas existen en la tabla a la que van a vincularse 10s controles, dato que podemos obtener facilmente de la propiedad Count de la tabla. Tambien necesitamos un medio para almacenar ese valor, asi como la posici6n actual, de forma que estkn accesibles durante el tiempo que el usuario est6 trabajando sobre la pigina. La soluci6n m6s fdcil es usar la propiedad Session para crear sendas variables y guardar dichos valores. En segundo lugar, tenemos que asignar de alguna forma 10s valores de las columnas de la tabla a 10s controles que haya en la pfigina. Si asignamos a la propiedad Text de un TextBox la expresi6n d s L i b r o s l . L i b r o s ( 0 ) . T i t u l o , por ejemplo, el control mostraria siempre el titulo de la primera fila, independientemente del valor que tuviera la variable de posicion creada anteriormente. La vinculaci6n entre tabla y controles, por tanto, debe efectuarse a mano. iCudndo realizar

Programacio'n de bases de datos con V i s u a l Basic .NET

esas asignaciones? En el momento en que el control reciba el evento DataBinding, generado cada vez que se llama a1 metodo DataBind ( ) del control o de la pzigina donde estii insertado.

Usa lutedace Design for Programmers SQL Servcr 2000 Gum practrca para u s u a ~ ~JBuilda s 7 P r o g r d con Visual C# NET Programa&n con J'tsual Shtdto NET Rogsaa~cib con V i Basic NET Gum pracbca para usuams de Vtsual Basic

Guia przict;ca para u s u a r b s de Visual Stodio

NET NET

Programanirn con Delph 6 y Kyhx Guia przicticaparausuasiosde Detpbi 6 h.lanual a\ atlzado Excel 2002

Guiapr&&apaia

muarm &Excel 2002

Guia practrca para usuanos de Kyhx

Intr&&

M

a la programackjn

d del rmaoprocesador60386

Assembly Langoage Step-by-step

Figura 14.9. Tabla generada por el componente D a t a L i s t

Puede realizar una prueba dando 10s pasos siguientes: Inicie una nueva aplicaci6n Web ASP.NET. Inserte desde el Explorador de servidores la tabla L i b r o s de uno de 10s origenes que tenga disponibles, por ejemplo SQL Server. Genere el DataSet a partir del adaptador de datos. Inserte en el formulario dos controles TextBox y dos Button. Haga doble clic sobre el formulario para abrir el m6todo correspondiente a1 evento Load, que quedaria asi: P r i v a t e Sub Page-LoadiByVal s e n d e r As System.Object, B y V a l e As S y s t e m . E v e n t A r g s ) H a n d l e s M y B a s e . L o a d

14. Componentes con vinculacidn a datos

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

El c6digo asociado a 10s dos botones que ha insertado serti el siguiente: But CllC 1 s e n d e r As S y s t e m . O b ] 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 r ! n l . C l i c k Dim Eori t 1 !n As I

Priva

~

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 " ) DataBind ( )

=

tosition

'

End If End Sub

Por ultimo, abra el mktodo correspondiente a1 evento DataBinding de uno de 10s TextBox, dejhdolo como se muestra a continuaci6n:

Private Sub T e x t B o x l DataBinding(ByVa1 s e n d e r As S y s t e m . O b j e c t ,

T e x t B o x l . T e x t = D s L i b r o s l .Libras ( S e s s i o n ( " P o s i t i o n " ) ) . T i t u l o T e x t B o x 2 . T e x t = D s L i b r o s 1 . L i b r o s ( S e s s i o n ( " P o s i t i o n " ) ) .Autor End Sub

Observe que la inicializacibn de las variables Position y Count se efectua s610 la primera vez que se abre la phgina, y no cada vez que se pulsa uno de 10s botones. Cstos recuperan el valor actual de Position y lo actualizan, invocando a continuaci6n a1 mktodo DataBind ( ) de la p6gina que, a su vez, provoca el evento

Programacidn de bases de datos con Visual Basic .NET D a t a B i n d i n g de 10s TextBox. En la figura 14.10 puede verse la p6gina mostrando 10s datos de una fila.

&dwo

Eddiom

4er

Favoritor

flwramientas

Amda

sy

- - + I 2

llek~O$BDD~aual6a~1d.l~/l4~a.egarASP/WebForm1 awx

Programacion con Visual Basic NET

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

Los controles ASI'.NET tampoco disponen de un sistema de edici6n y actualizaci6n autom6tica de 10s datos. Los cambios en la informaci6n mostrada por 10s controles deben detectarse, facilitando, en caso de ser necesario, 10s elementos para efectuar dicha edici6n. El componente D a t a G r i d , por ejemplo, puede mostrar una serie de enlaces como columnas de la rejilla, haciendo posible la edici6n y eliminaci6n de datos. En cuanto a la actualizacion de 10s datos en el origen, necesitar6 disponer en el formulario algun boton o enlace que, a1 ser pulsado, ejecute el c6digo de sincronizaci6n de 10s cambios con el servidor del que procede la informaci6n. Esto significa, por regla general, o utilizar un objeto Command con la sentencia SQL a ejecutar 0, si estamos usando un adaptador de datos y un D a t a S e t , servirnos del mecanismo habitual de actualizacibn que ya conocemos.

Usando 10s controles de las secciones Web Forms o Windows Forms, segun el tide aplicaci6n que se trate, pueden disefiarse formularios que permitan a1 usuario ver 10s datos, navegar por ellos, editarlos, afiadir y eliminar datos. Para ello necesitard combinar gran parte de 10s conocimientos que ha adquirido desde el principio de este libro, desde la definici6n de la conexi6n con el origen de datos hasta la vinculaci6n de 10s controles, pasando por la creaci6n de adaptadores y conjuntos de datos o la codificacih de las sentencias necesarias para actualizar el origen. Visual Studio .NET dispone de sendos asistentes que facilitan el disefio de estos formularios, ahorrdndonos gran parte del trabajo que, de otra forma, tendriamos que efectuar manualmente. El objetivo de este capitulo es mostrarle c6mo servirse de estos asistentes para disefiar sus propios formularios, usando, como en 10s demds capitulos, alguna de las bases de datos creadas en el tercer capitulo. PO

ara forrnularios Windows Comenzaremos analizando el asistente de formularios de datos para Windows, creando una aplicacih Windows tipica, eliminando el formulario afiadido por defecto e iniciando este asistente. Para ello seleccione la opci6n Proyecto>Agregar nuevo elemento, o pulse el b o t h equivalente, y seleccione del cuadro de didlogo que aparece el elemento Asistente para formularios de datos (vease figura 15.1). Introduzca en la parte inferior el nombre que dard a1 formulario y pulse el b o t h Abrir.

a

15. Formularios de datos

I

0Elernentos de proyecto local 3 Interfaz de usuario 3 Codigo

DataSet

Arthivo XML

Archivo XSLT

As[stente p a famukbs

Esquema XML

Y oat95

2 Web

a Utilidad ...

Figura 15.1. lniciamos el asistente para creacion de un formulario de datos Windows

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 automdticamente 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 sobre 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 introduzca 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

Elegir el conjunto de datos que desea utilizar El conjunto de dams contiene las tablas y las columnas con las que va a tabalar en el formulario

E l m te ayuda acrearun w e y o de dates. De forma dhzmathra, proyecto un conju&o de dabs ya defintdo o uno propt~dwradopos un mwcio Web. ZQu6 conjunto de dabs derea utitizar?

F pear

INI

nuevo conJUnt0 de datos denommado:

ldsLlbrosl

Figura 15.2. Seleccionamos crear un nuevo conjunto de datos

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 desplegar la lista que aparece a la izquierda para elegirla. De no ser dse el caso, pulsariamos 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, como es logico, la conexi6n seri otra diferente dependiendo de d6nde estd ejecutdndose 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.

de 10s elementos de origen Para crear nuestro formulario podemos partir de tablas, vistas, procedimientos almacenados que devuelven resultados, etc. En este paso del asistente el cuadro de diilogo esti dividido en dos paneles. El de la izquierda nos muestra las tablas, vistas y, en general, todos 10s elementos que han podido encontrarse a travds de la

15. Forrnularios d e datos

conexidn definida en el punto previo. En el panel de la derecha, inicialmente vacio, irAn apareciendo 10s elementos que seleccionemos, usando para ellos 10s botones que hay en la parte central.

Elegir una conexion de datos La conexion de d a b s especifica como buscar e iniciar una sesion en un servidor y una base de d a b s especificos

-

de conenones de datos que esti astualrnente en d e w a d o r de sewidores o agregar una nueva conendn b que d e w nu aparece en b ksta. ZQu6 mne&indebe utllbarel asi+twte?

I

S

r

l

Nueva L o n e ~ ... n

Figura 15.3. Seleccion de una conexion con el origen de datos

Como puede verse en la figura 15.4, hemos elegido del origen las tablas Edit 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 facilitar una lista de parametros de entrada.

Cuando creAbamos, mediante cddigo, un D a t a S e t a partir de sendos comandos para obtener el contenido de dos tablas, un paso imprescindible era el estable-

Prograrnacidn de bases de datos con V i s u a l Basic .NET

cimiento de la relaci6n entre dichas tablas, ya fuese credndola explicitamente o bien recuperdndola con anterioridad de un esquema que hubi6ramos guardado.

Elegir tablas o vistas Las tablas o vistas que seleccione determinaran que columnas estaran disponibles para anarecer en el formulario

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.

Oementos disponibles: +

Bementos sekcionados:

Tablas vistas

I-,

_1_1

1

Tablas Editoriales Llbros vistas

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 elementos 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) bastar6 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, momento 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 columnas, 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 aprecia en la figura 15.6. En el de la izquierda elegimos la tabla maestra de la lista desplegable, 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

un Mmbre a la nueva r e k & bs tabla6 y los campos de daves primanos y secundanosy. a conbnw&~, agreguela a la

Las rebctones se basan en dares c m e s enfze l a tabtas. A%lrsta de relaaones uWaando el W n de Recha Nomkre:

&elaoones:

IFKLibrosEditorial

Tabla primaria:

TaMa s e c & a n a :

Editor ia les

ILibros

paves: IDEditorial

Figura 15.5. Definimos la relacion que existe entre las dos tablas

Elegir tablas y columnas para mostrar en el formulario El forrnulario puede rnostrar cualquiera de las tablas y columnas disponibles en el conjunta de dabs 5, w s f z a

m& de una tabla en d fwdario, !atabbs benen una r

i”=”

W ptinopal-detdfe

&Ztd! t a b b y cofunmas dese&nasbar en el fonnubrb? Tabla de &etaks:

i l-,l

ILibros

i

CQ!UKWW:

Figura 15.6. Seleccion de las columnas a usar en el disefio del formulario

Para nuestro formulario de ejemplo dejaremos marcadas todas las columnas aunque, en la pr6ctica, podrian desmarcarse algunas como IDEditorial,IDLibro o Editorial.

Prograrnacidn de bases de datos con V i s u a l Basic .NET

____

El tiltimo paso del asistente nos permite elegir el disefio que deseamos darle a1 formulario, existiendo dos opciones: 0

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. Registro unico en controles individuales: Se usan controles de interfaz tipicos, como T e x t B o x y CheckBox, para mostrar la informaci6n fila a fila.

Dependiendo de la opci6n por la que optemos, en la parte inferior de la ventana (vkase figura 15.7) estaran accesibles mAs o menos apartados. Si elegimos usar rejillas de datos, que es lo que nos interesa en este caso, tan s610 podemos indicar si queremos que se afiada a1 formulario un b o t h para cancelar todos 10s cambios o no. En caso de utilizarse controles individuales, mostrando solo una fila en cada momento, podremos elegir 10s botones que se afiadirAn para tareas de edici6n.

Elegir el estilo de presentacion

$re.ssrzP I

Puede mosb-ar un unico reqab-o cada vez o mosfar todos

icdmo &sea Rlostrar ks datos?

F lodo5 lo5 regisbos &e la cuadricula r Regrstro i r ~ en o conboles rndrvrduales ZQmS wntrdes adicionakr desea para el fonnuhrio?

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

Aparte de 10s botones que indiquemos explicitamente, marcando las opciones de este paso del asistente, el formulario contara tambikn con.otros que se incluyen por defecto, como un b o t h para recuperar 10s datos y otro para ejecutar la actualizaci6n.

15. Forrnularios de datos

___ - -_________ - -__-A1 pulsar el b o t h Finalizar del asistente 6ste se cerrar6 y nos encontraremos con nuestro formulario, con su aspect0 por defecto. L6gicamente puede personalizar dicho disefio, modificando titulos y disposicih de 10s botones o 10s DataGrid, aiiadiendo nuevos elementos para realzar la interfaz, etc. En nuestro caso nos hemos limitado a modificar el ancho del segundo DataGrid, cambiando tambidn la propiedad D o c k de ambas cuadriculas para que se adapten automdticamente en caso de que se ajusten las dimensiones del formulario. En la figura 15.8 puede ver el formulario en el entorno de Visual Basic .NET tras 10s cambios. *

___-I_

-__.

ForrnularloAsstpnte (1 FmdabAsiotente References Assernblylnfc vb dstibras nsd hnhbrm rb

IUClOn

3

a

.r ob)diiibras

% OlrDbConnemonl

boleDbDataAdaprer1

b OleDbDataAdapter2

Figura 15.8. El formulario en el entorno de disefio

Nota Observe, en la parte inferior del area de diseiio, 10s componentes de acceso a datos que ha generado el asistente: uno para la conexion, dos adaptadores de datos y el D a t a S e t .

Prograrnacidn de bases de datos con Visual Basic .NET

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 efectuados. Analicemos brevemente ese c6digo para saber exactamente qu4 ocurrir6 a1 ejecutar el programa.

.

....* < ' .

'.

Antes de ejecutar el programa tendra que abrir la ventana de propiedades del proyecto y establecer el formulario recien generado como elemento de inicio.

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 ejecuci6n del c6digo siguiente: Private Sub k t r l l i j a d C l i c k ( B y V a 1 s e r i d e r As System.Ob]ect, ~

B y V a l e As S y s t e r n . E v r n t A r g s 1 H a n d l e s b t r l L o a d . r1ic-C

-

~

T rY

C y s t em. hi r1j J w c

. F Jim'.

Mes s a n e B )x . Stlo,$ ! e L c ad. Me5 5 a q t )

End T r y End Sub

Lo unico que se hace es invocar a1 metodo LoadDataSet ( ) del propio formulario, controlando una posible excepcion. El bloque de c6digo que hay detr5s del C a t c h est6 diseiiado para que introduzcamos nuestro control de errores personalizado, ya que el asistente lo que hace es mostrar el posible error en una ventana. El c6digo del metodo LoadDataSet ( ) es el mostrado a continuacih: 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 devuelve 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 obtenidas por la llamada a Fi 11Data Set ( ) . En ese momento el formulario ya apareceria 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.

Anaya Multimedia McGrawHiII

Telemaco 43 Editicio Valrealv 1' planta 901 Grayson Street 605Third Avenue NewYork

1 IDLibro 1 ISBN 4

5 6 7 8 9 10

84-415-1324-4 84-415-1392-9 84-41 5-1 376-7 84-41 5-1 351-1 84-415-1290-6 84-41 5-1 291-4 84-415-1 261-2

-

-

- _ IAutor

Guiapradicaparausuarios JBuilder 7 Programacion con Visual C# NET Programacion con Visual Studio NET Programacion con Visual Basic NET Guia practicapara usuarios de Visual Basic NET Guia pradica para usuarios de Visual Studio NET Programacion con Delphi 6 y Kylix Guia pradica para usuarios de Delphi 6 Manual avanzado Excel 2002 Guia practica para usuarios de Excel 2002

Francisco Charte Francisco Charte Francisco ChartefJorge Ser 1 Francisco Charte Francisco Charte Francisco Charte Francisco Charte

Figura 15.9. El formulario con las filas ya en las cuadriculas de datos

La pulsaci6n del b o t h Cancelar se resuelve con una simple llamada a1 m6todo Rejectchanges ( ) del DataSet. El b o t h Actualizar desencadena un proceso bastante m i s complejo que se desarrolla, inicialmente, en el metodo asociado a1 evento Click. Este, bisicamente, se limita a invocar a1 metodo siguiente: Public Sub UpdateDataSetO

Dim o b i DataSetChanges As ForrnularloAslstente . d s L l b r o s New FormularioAsistente.dsLibros( )

=

-

15. Forrnularios de datos

Me. B 1 r d i rig C o n t e x t ( '1)b jd sL i br (2s , " E d i t o r i a 1 e s " ) . Er,dCiJ r r e n t E d i t ( Me.B i r d i n g C o n t e x t j ODj d s L i b r o s , "Libros" j . E r d r u r r e r i t E d i t [ )

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

En principio se llama a1 metodo EndcurrentEdit ( ) del objeto BindingManagerBase de cada tabla, finalizando asi cualquier operaci6n de edici6n que pudiese haber en curso. Observe c6mo se utiliza la propiedad Bindingcontext del formulario explicada en el capitulo previo. A continuaci6n se recuperan, en un DataSet temporal, 10s cambios que se han efectuado en el formulario, usando para ello el metodo Getchanges ( ) del dsLib r o s . Tras comprobar que, efectivamente, hay cambios pendientes de consolidar, se llama a1 mbtodo UpdateDataSource ( ) y combinan 10s cambios en el conjunto de datos a1 que estdn vinculados 10s controles. El metodo UpdateDataSource ( ) , recibiendo como pardmetro la lista de cambios, se encarga de abrir de nuevo la conexi6n e invocar a1 metodo Update ( ) de cada adaptador, facilitando la informaci6n a1 origen de datos. Public Sub U p d a t e D a t a S o u r c e (ByVal C h a n g e d R o w s As Fo rmu 1 a r 1 o A s 1s t e n t e . is L 1b rrr s ) T rY

Prograrnacidn de bases de datos con Visual Basic .NET 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 Throw npziat rl A i,pt Finally

I )ri

End Try End Sub

Nota En lugar de recuperar 10s cambios en un D a t a S e t temporal, tambien podria haberse empleado el original como parametro para el metodo U p d a t e ( ) de 10s adaptadores. Sin embargo, en caso de que la actualizacion devolviese algun error este se veria reflejado en las filas del conjunto de datos que hay vinculado con 10s controles.

Si conocemos el asistente para formularios Windows, y el c6digo que genera, el asistente para formularios Web nos resultar6 realmente familiar, puesto que 10s pasos son exactamente 10s mismos: selecci6n o creaci6n de un D a t a S e t , definici6n de la conexi6n a emplear, elecci6n de 10s elementos y columnas de origen y establecimiento de la relaci6n entre las tablas. La unica diferencia es que en este caso no podemos elegir entre dos diseiios distintos de formulario, puesto que el asistente siempre genera uno basado en el us0 de controles D a t a G r i d , f6cilmente vinculables a origenes de datos. Inicie un proyecto de aplicaci6n Web ASP.NET, elimine el formulario que aparece por defect0 y recurra a1 asistente, que se encuentra en el mismo lugar que el de formularios Windows, escogiendo las mismas opciones en cuanto a conjunto de datos, conexibn, columnas, etc. El resultado final deberi ser similar a1 de la figura 15.10, un formulario compuesto por un b o t h , en la parte superior, y dos D a t a G r i d . Estos se encuentran vinculados con el D a t a S e t que aparece en la parte inferior. A1 ejecutar el proyecto ver6 que, tras pulsar el b o t h Cargar, tan s610 aparece la cuadricula con la lista de editoriales. A1 pulsar el enlace que aparece en la primera columna de cada fila, se hard visible la segunda cuadricula con 10s libros que correspondan a la editorial elegida, como se ve en la figura 15.11. Sin embargo, no obtenemos funcionalidad alguna de edici6n por parte de este asistente.

15. Formularios de datos

hlostrar hlostrx Mostrar Mostrar

detalles

detalles detdles detdles

IDEditorhl

Nombre

0 1 2 3

abC

abC

abC

abC

abC

abC

abC

abC

DireccIon

abC ~

DataBound DataBound DataBound DataBound DataBound

DataBound DataBound DataBound DataBound DataBound

?&OleDbDataAdapterZ

DataBound DataBound DataBound DataBound DataBound

& OleDbDataAdapterl

_

_

DataBound DataBound DataBound DataBound DataBound

t% OleDbCannecbonl

_

~

p

-

DataBound DataBound DataBound DataBound DataBound

DataBound DataBound DataBound DataBound DataBound

& objdsiibros

~

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 capacidades 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: Private Sub buttonLoadpClick(ByVal s e n d e r As System.Object, ByVal e As System.EventArgs) Handles buttonLoad.Click T rY Me.LoadDataSet ( ) Me.masterDataGrid.SelectedIr4dex = -1 Me.masterDataGrid. D a t a B i n d ( )

Me.detailDataGrid.Visible = F a l s e Application ["objdslibros") = Me.objdsLibros Catch eLoad As System.Exception Me.Response.Write(eLoad.Message) End Try E n d Sub

\Iostra detallss

1

h a 1 a \luttnueda SIcGran Hd

Telemaco 43 Edmcto V&e&

2

.4presc

901 Graxson Street

\Ioctrar d e t d r c \forttar

1

4 < 6

dctdcb

Francisco Charte Francisco Charte

1 1

10

Francisco Chate Francisco C hate Jorpe Smano

1

39

Frannsco Chmte Frannsco Chmte Franasco Chart? Frmcisco Charte Frannctsco Chme

1 1

40

Progmacroti con \ ~sualBasic \TT

1

10 ' 5

GIM prachca para usuanoc de Visual Basic YET

9

&a prachca para usuanos de \-isualStudo \;ET Progemacton con Delplll6 \ h r h h a practlca para usuanos de Delph 6 \Ianual nanzado Excel 2001 &a prachca para usuanos de Excel 2002

11

I? 17

11 15 1-

10 - 4

SQL S m a 2000 Gua prachca pma usuarios Budder Progamacion con Visual C= M T Progamacion con 'iisual Studm 'iTT

S 10

l'planta

Gua prachca para uiuanos de K i h Inaoduccion a la programaaon Assembh LanguaSs Step bi Step

Francisco Chmte Frannsco Chmte \I Jesus Luque Francisco Charte Francisco Chme JeffDuntemann

-'

39

1

10 '1

1

3' 26

1

10 ' 2

1

21 01

1

10 52

1

10 ' 2

1

24 0 1

1

60 5

Figura 15.11. El forrnulario ejecutandose en Internet Explorer

Lo primero que encontramos es la invocaci6n a1 metodo L o a d D a t a S e t ( ) que, junto con F i l l D a t a S e t ( ) , se encargara de recuperar todos 10s datos en el objeto o b j d s L i b r o s que se ha insertado en el formulario. Esos dos metodos, LoadDat a S e t ( ) y F i l l D a t a S e t ( ) , son identicos a 10s explicados previamente en 10s comentarios a1 c6digo del formulario Windows. Act0 seguido se establece que no haya una fila seleccionada en el primer D a t a G r i d , vinculandolo con 10s datos y ocultando el D a t a G r i d de detalle puesto que, en principio, no tendria contenido alguno a1 no existir una editorial elegida. Por ~ l t i m ose , guarda en una variable del objeto A p p l i c a t i o n la referencia a1 objeto que contiene 10s datos, ob j d s L i b r o s , para facilitar el acceso a el desde otros metodos.

15. Formularios de datos

En este momento tendriamos el formulario con la primera rejilla mostrando las editoriales. Hasta que no se pulse el enlace Mostrar detalles de una de las filas la pagina quedard estatica. Cuando eso ocurra, se generard el evento S e l e c t e d I n d e x c h a n g e d y, en respuesta, se ejecutar6 el c6digo siguiente: 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

,

Tables ( " E d i t o r i a l e s " ) c u r r e r ~ t E ' i i r c r , t R i ) w= ( M e . r i d s t e L [)a t ar;ricj ~

. Se 1ect e ' jI r l ' ? i - x )

~

cu r r en t E'a re r, t R,-Iw . C rc a t e Cki i 1f d V ie ~ d( " FK I, M e . d e t a i 1Data ti r i d . Da t a Source = cti i 1 d K O W F Me. d c t a i 1[la t a G r i d . l)a t a Bi rl,d ( 1 Me. d P t a i 1 Da t u tir i (3.V 1s i b 1e = T r u e Else M e . drt a i 1P a t a G r i ?: . V i s i k > le = F a l s e E n d If E n d Sub

1

bri1.s

E d i t o r i a 1" )

A pesar de la extensih, en cuanto a numero de sentencias, el proceso que ejecutado es relativamente simple, lo que ocurre es que se efectua paso a paso. Se utiliza una vista, p a r e n t R o w s , para obtener una referencia a la fila que esta elegida actualmente en el D a t a G r i d maestro. Con esta informaci6n se utiliza el metodo C r e a t e C h i l d V i e w ( ) de la fila para obtener el conjunto de filas de detalle, enlazandolo con el segundo D a t a g r i d y haciendo este visible. \

.......

1.:

.........................

.....................

......

A la vista est6 que el formulario generado por el asistente para aplicaciones Web queda lejos de tener la funcionalidad que ofrecen 10s formularios Windows, no facilitando las operaciones de edici6n. Si queremos esta funcionalidad, tendremos que afiadirla nosotros mismos. Para ello hay que afiadir nuevos enlaces a1 Dat a G r i d que contengan 10s datos a editar, por ejemplo el que muestra 10s libros, asi como c6digo para gestionar 10s eventos que generen. Es lo que vamos a hacer en 10s puntos siguientes.

El primer paso sera afiadir a1 segundo D a t a G r i d 10s enlaces necesarios para que, en ejecucibn, cada fila disponga de un enlace que permita entrar en modo de edici6n. Haga clic con el bot6n secundario del rat6n sobre el segundo D a t a G r i d ,

Programacidn de bases de datos con Visual Basic .NET

para abrir el menu emergente, y luego seleccione la opcion Generador de propiedades. Se abrira un cuadro de didogo con multiples apartados a 10s que puede acceder con 10s botones que aparecen a la izquierda. Pulse el boton Columnas (vease figura 15.12) para acceder a la lista de columnas de la cuadricula.

1General

J Columnas 3 Paginacmn d Formato

3 Bordes

r grear columnas a u t m d t k a m t e en tempo de ejecucion ____ _

Lrsta de ED

Columnas disponrbles:

Columnasselecaonadas

0 C o b m enlazada Columna Hipervinculo

W Columna Plantilla Propiedadesde EdKommandC&mn Texto del mcabezado:

... . .

......- _.

Texto del pie:

I Expresih de _wdem&n:

r] p yisibb

. I

Converbr esta colurnna en una columna Plantilla Cancebr

1

I

I

Ayuda

I

Figura 15.12. Aiiadimos a la rejilla una nueva columna para el boton de edicion

Elija en el apartado Columnas disponibles la secci6nColumna de boton, aiiadiendo a Columnas seleccionadas un elemento Editar, Actualizar, Cancelar. Coloquelo como primer elemento, para que aparezca como la columna m6s a la izquierda de la cuadricula. Si quiere puede personalizar el texto de 10s enlaces, asi como cambiar el Tip0 de boton que, por defecto, es LinkButton. Cierre el cuadro de didogo pulsando el b o t h Aceptar. VerA que el D a t a G r i d ya muestra el enlace o b o t h para editar cada fila, pero si ejecuta el programa no obtendr6 respuesta alguna a la pulsation sobre 61.

,- \

I.1 I

-

Los enlaces o botones aiiadidos como columnas de un D a t a G r i d , en nuestro caso el enlace Editar y 10s enlaces Actualizar y Cancelar que apareceran tras pulsar el anterior, generan eventos a1 pulsarse sobre ellos, concretamente 10s eventos

Programacidn de bases de datos con Visual Basic .NET Handles d e t a 1 1 Da t a Gr i d . C a n ce 1 Cornmarld detailDataGrid.EditIternIndex ShowDetailGrid ( ) ' End Sub

=

-1

Simplemente asignamos el valor -1 a EditItemIndex, para finalizar la edici6n que estaba en curso, y llamamos a ShowDetailGrid ( ) ignorando 10s cambios que se pudiesen haber efectuado. La cuadricula vuelve a aparecer con sus datos originales, ya que no existe una conexi6n directa entre 10s TextBox que muestra el DataGrid y 10s DataRow del conjunto de datos subyacente. Por Liltimo, tendremos que codificar el metodo del evento Updatecommand que, como se puede ver, es bastante mQscomplejo que 10s dos anteriores: Private (ByVal source As Object, ByVal e As System.Web.UI.WebContro1s.DataGridC~~mmar~dEver~tArgs) ~

Dim F l L d AS dsLibros.LibrosRow = obldslibros. Libros. FindByIDLibro ( CType(e.Item.Cells(l).Controls(O),TextBox).Text) ~

~

If Not F i l a Is Nothing Then

.

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

Tras recuperar la referencia a1 DataSet, almacenada como variable en la propiedad Application de la pAgina, buscamos en 41 la fila que corresponde a1 libro que estQeditiindose. Se obtiene un objeto LibrosRow, que no es mAs que un derivado de DataRow en el que existen propiedades especificas para el acceso a las columnas de esta tabla. Observe c6mo se recupera el control que hay en cada celdilla, mediante la expresi6n Cells (n). Controls (O), convirtiendolo en un TextBox para poder leer el texto que contiene. La primera celdilla, a la que corresponde el indice 0, es

15. Forrnularios de datos

la que contiene 10s enlaces de edition, asi que el identificador del libro se encuentra en la segunda y 10s demiis datos en las siguientes. Los recuperamos asignando10s 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 ejecutarlo, comprobara que esos cambios se pierden. Tenemos que actualizar el origen de datos. 2

ii 811

___

-__-_

No tiene sentido actualizar la informaci6n con el origen cada vez que se modifique 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, insertaremos ese b o t h a la derecha del que ya existia en la parte superior de la pagina

Haga doble clic sobre el b o t h e introduzca el c6digo siguiente: Private Sub B u t t o n 1 Cllck(ByVa1 s e n d e r As System.Ob]ect, ~

Prograrnacidn de bases de datos con Visual Basic .NET B y V a l e As System.EventArgs) Handles Buttonl.Cllck

Catch Exceprlon As E.xcrptlnn 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 hemos optado por algo mucho m6s directo. Recuperamos la referencia al DataSet y lo usamos directamente como parhmetro del mktodo Update ( ) del segundo adaptador 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 navegador Web.

15. Formularios de datos

Tomando como base todo el proceso descrito, puede aAadir al miSmODataGrid la posibilidad de eliminar cualquiera de sus filas y tambien la de aAadir filas nuevas. Le resultara un buen ejercicio para conocer mas detalles sobre D a t a G r i d . El proceso de actualizacion con el origen de datos le servira tal cual esta.

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 formularios con controles vinculados a datos tanto en aplicaciones Windows como en aplicaciones Web. Ha podido ver que el asistente para formularios Web genera menos funcionalidad 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, principalmente 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 directa 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 hecho 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 informacibn, como en 10s capitulos previos, per0 sin emplear directamente las clases 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.

En el quinto capitulo, dedicado a1 estudio del modelo de objetos ADO.NET, conocio multiples interfaces que eran implementadas por clases de cada proveedor de datos. A mod0 de recordatorio, las interfaces que podriamos considerar miis interesantes son las siguientes:

16. Conexidn genhica

IDbConnect ion:Implementada por SqlConne ction,01eDbConnect ion, Oracleconnection y OdbcConnection, define el conjunto de metodos base para trabajar con una conexi6n estableciendo la cadena de parimetros, abriendola y cerrfindola, etc. 0

IDbCommand:Esta interfaz, implementada por las clases SqlCommand, OleDbCommand, OracleCommand y OdbcCommand, establece el conjunto de miembros necesario para definir un comando y ejecutarlo, ya sea obteniendo a cambio un lector de datos o no. IDataAdapter e IDbDataAdapter:La primera define 10s mktodos Fill ( ) y Update ( ) que hemos empleado repetidamente para llenar un DataSet o actualizar el origen, mientras que la segunda declara las propiedades SelectCommand,InsertCommand,UpdateCommandy DeleteCommand.La clase Da taAdap te r, tambien generics, se encarga de implementar 10s dos primeros metodos y servir como base de DbDataAdapter que, a su vez, es la base comun de SqlDa taAdap ter, OleDbDa taAdap ter, OracleDa taAdapter y OdbcDataAdapter. Estas implementan directamente la interfaz IDbDataAdapter. IDataReader:Interfaz implementada por las clases SqlDataReader, OleDbDataReader, OracleDataReader y OdbcDataReader, que facilitan la lectura unidireccional de conjuntos de datos sin posibilidades de edici6n.

Si necesita refrescar m i s la memoria observe las figuras 5.2, 5.3 y 5.4, en las cuales se representaban esquemiticamente las relaciones entre estas interfaces y las clases que las implementan. En el punto siguiente las usaremos para escribir un ejemplo que pueda operar indistintamente sobre una base de datos Access, SQL Server u Oracle.

DiseCio de la interfaz de usuario Comenzaremos creando el formulario Windows en el que incluiremos todo el c6digo. Su finalidad seri permitirnos seleccionar una conexi6n de tres posibles, introducir un comando de selecci6n y ejecutarlo, mostrando 10s resultados en una cuadricula. Inicie un nuevo proyecto e inserte en el formulario 10s elementos que puede ver en la figura 16.1: tres botones de radio en un grupo, un cuadro de texto para introducir la sentencia, un b o t h para recuperar 10s datos y un DataGrid ocupando toda la parte inferior. Puede asignar identificadores mis coherentes a 10s controles, asi como modificar ciertas propiedades, como Anchor, para que 10s controles se ajusten automiticamente a 10s cambios de tamafio del formulario. Como puede verse, el ejemplo s610 recuperari informaci6n del origen seleccionado, per0 igualmente podrian afiadirse 10s elementos necesarios para facilitar la edici6n y actualizaci6n.

Prograrnacidn de bases de datos con Visual Basic .NET

( I -

3

Figura 16.1. Diseiio del forrnulario

e funciones El paso siguiente ser6 la codificaci6n de 10s procedimientos y funciones necesarios 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 Dim Dim Dim

Coriexion As I D b C o n n e c t i o n Comando As IDbCommand A d a p t a d o r As I D b D a t a A d a p t e r 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=" & " L i b r n s ; riser I D = s a " ) e w SqlDataAdapterO Case 3 ' w OracleConnection ( " D a t a Source=Libros; User ID=scott; Password=tiger"l Adaptador = N e w O r a c l e D a t a A d a p t e r ( ) Case E l s e ' 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

""

Como puede ver, se asigna a la variable Conexion un OleDbConnection, Sqlconnection u Oracleconnection, dependiendo del boton de radio seleccionado. Tambien se crea el adaptador de datos especifico. Observe que la creaci6n de comando es generica, pudiendose haber efectuado en cualquier otro punto del programa sin necesidad de tener que conocer el tip0 real del objeto a1 cual apunta Conexion. Si este metodo devuelve el valor True,porque se hayan creado satisfactoriamente 10s objetos y, ademss, el cuadro de texto no est6 vacio, se proceder6 a ejecutar el metodo AbrirConexion ( ) : 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

Simplemente se usa el metodo Open ( ) de IDbConnection para abrir la conexidn, notificando un posible fallo que pudiera producirse. Despues se ejecutar6 el metodo RecuperarDatos ( ) que, tal y como se puede ver a continuaci6n, prepara el comando, lo enlaza con el adaptador y crea el conjunto de datos: 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.

Por ultimo tenemos el m6todo VincularRejilla ( ) en el que, con dos simples asignaciones, se enlaza el DataGrid con la tabla creada en el DataSet. h a , a1 no haberse facilitado ningun nombre a1 llamar a1 m6todo Fill ( ) del adaptador, siempre se llama Table.

P r i v a t e Sub VincularRe]illa

DataGrid1.DataSource Da t a G r 1 d 1 . D a t aM emb e r End Sub

= =

( )

dsDatos " T ab 1 e "

No necesita ninguna preparacih adicional para ejecutar este proyecto, asumiendo que tiene instalado el proveedor para Oracle y que ha afiadido la correspondiente referencia a su ensamblado en el proyecto. De no ser asi, elimine el c6digo que hace us0 de 10s objetos OracleXXX. A1 ejecutar el programa tendri el formulario vacio, tal y como aparecia en la figura 16.1, debiendo seleccionarse una de las tres conexiones disponibles e introducirse un comando de seleccih. En la figura 16.2 puede ver el resultado de una sentencia en la que se combinan las tablas de editoriales y libros. Una vez introducida la consulta, no hay m6s que cambiar de proveedor y volver a pulsar el b o t h Recuperar para obtener 10s datos de otro origen. De no existir las interfaces gen6ricas indicadas en el primer punto del capitulo, la creaci6n de un programa como 6ste hubiese requerido mucho m i s cbdigo, pricticamente el triple, a1 tener que codificar la apertura y el resto de acciones de manera especifica para cada proveedor.

Programacidn de bases de datos con Visual Basic .NET

Anaya Multimedia Anaya Multimedia Anaya Multimedia Anaya Multimedia Anaya Multimedia Anaya Multimedia Anaya Multimedia Anaya Multimedia Anaya Multimedia McGrawHiII Anaya Multimedia Anaya Multimedia Anaya Multimedia Anaya Multimedia Anaya Multimedia Apress

Assembly Language Step-by-step Guia pradica para usuarios de Delphi 6 Guia pradica para usuarios de Excel 2002 Guia practica para usuarios de Kylix Guia practica para usuarios de Visual Basic NET Guia pradica para usuarios de Visual StudicI NET Guia pradica para usuarios JBuilder 7 lntroduccidn a la programacion Manual avanzado Excel 2002 Manual del microprocesador 80386 Programacion con Delphi 6 y Kylix Programacion con Visual Basic NET Programacion con Visual C# NET Programacion con Visual Studio NET SQL Sewer 2000 User Interface Design for Programmers

Jeff Duntemann Francisco Charte Francisco Charte/M Jesus Luque Francisco Charte Francisco Charte Francisco Charte Francisco Charte Francisco Charte Francisco Charte Chris H Pappas&William H Murr Francisco Charte Francisco Charte Francisco Charte Ojeda Francisco Charte/Jorge Serrano Francisco Charte Oleda Joel Spolsky

Figura 16.2. El programa en ejecucion

60.5 10.52 10.52 10.52 10.75 10.52 10.75 24.04 21.04 40 37.26 39 39 40 10.75 31

El RDBMS de Oracle es el miis utilizado a escala mundial, especialmente en sistemas de tamafio medio y grande, lo cual no es de extrafiar pues se trata de una de las empresas con m6s experiencia en el sector, una empresa que ha hecho de su producto de base de datos el centro de todo su negocio. A pesar de las mejoras introducidas en las versiones 8i y 9i, lo cierto es que Oracle no resulta un RDBMS fiicil de instalar ni administrar, tarea que suele quedar encomendada a administradores de bases de datos especializados en este producto. No obstante, como programadores acostumbrados a utilizar herramientas de distinta naturaleza, nos debe resultar mds fiicil usar Oracle que a un usuario que tan s610 tenga conocimientos biisicos. En 10s capitulos de la primera y segunda parte se han dado varios pasos para, a1 final, llegar a usar una base de datos Oracle desde una aplicaci6n Visual Basic .NET. El objetivo de este capitulo es mostrarle, de forma resumida y riipida, cu61 seria todo el proceso de configuracih necesario.

De partida, como es 16gic0, deber5 contar con un servidor en el que est6 ejecutindose 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 trabajar ya tenga el RDBMS instalado y en funcionamiento, per0 tambi6n es seguro que

Programacidn de bases de datos con Visual Basic .NET

El proceso de instalaci6n de Oracle9i es bastante largo, si bien nuestras intervenciones en el proceso se limitarh, en la mayoria de casos, a elegir una opci6n y pulsar el b o t h Siguiente para ir avanzando. En este punto puede ver un resumen del proceso y ver, paso a paso, las p6ginas que deberia mostrarle el asistente. Tras iniciar el instalador, ejecutando el archivo s e t u p . exe del primer CD, deber5 aparecer el Instalador universal de Oracle. Este le permite, como se aprecia en la figura 17.2, tanto instalar nuevos productos como ver 10s que tiene instalados o desinstalar aquellos en 10s que ya no est6 interesado. En este caso, puesto que queremos instalar el RDBMS y 10s productos de que depende, pulsariamos el citado b o t h Siguiente. OrklTe.""ine;;al .

.

. ..

. .

. .,...

.-,- .,.

. ..

"

," - .

- .. -.- .....-

-

. . .. ~..;--. *..,. . ,.%.

.

.... .... .

-.

cia _.

.- .

.-.. ..-

Bienvenido Oracte universal Installer le guiarh en la instalacion y confuuracdn

Haga clic en "Productos lnstalados '' para ver todos los productos

Figura 17.2. Ventana principal del instalador universal de Oracle

Lo primer0 que tenemos que hacer, antes incluso de elegir el product0 que queremos 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 habitualmente 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

Ubicacion de 10s Archivos Origsn... IntroduZCa l a ruta

Ruta de ACC~SO

Figura 17.3. Seleccion del directorio raiz donde se efectuara la instalacion

Finalizada la lectura del archivo j a r, el instalador nos mostrara la lista de opciones que tenemos a nuestra disposicih. En este caso son tres (vease figura 17.4), de las cuales nos interesa, en principio, la primera, instalando la base de datos completa en el sistema. La dejamos marcada y luego pulsamos nuevamente el bot6n Siguiente. El paso siguiente nos permitir6 elegir una de las ediciones de Oracle9i, Enterprise, Esta'ndar o Personal. Dependiendo de la edicidn se instalarin mas o menos servicios y herramientas. Para el objetivo que perseguimos es indistinta la edici6n por la que optemos, puede ser cualquiera de las tres disponibles. A1 tiempo que se instala el RDBMS, el asistente de instalacion tambien puede crear una base de datos evitandonos ese trabajo posterior. En la ventana que aparece en la figura 17.5 puede ver que aparecen distintas opciones. Si no quiere crear una base de datos, sin0 instalar el software sin mis, elija So10 Software. Las demis opciones crean una base de datos, optimizindola para el procesamiento masivo de transacciones, el almacenamiento de datos para analisis o un us0 general. Dejamos marcada la primera option, que aparece elegida por defecto, y pulsamos el b o t h Siguiente. Las bases de datos Oracle se identifican con un nombre global y un SID o identificador simple dentro del servidor. Es la information que tenemos que facilitar en el paso siguiente. A medida que introduzcamos el nombre global veremos que el mismo asistente propone un SID que, normalmente, aceptaremos. En este caso (vease figura 17.6) asignamos el nombre global Libros .AnayaMultimedia.e s a la base de datos, con el SID Libros.

Programacidn de bases de datos con Visual Basic .NET

Productos Disponibles Seleccione el product0 que dosea InStrlar. 5 Oracle91 Database 9 0 1 1 1 lndsia uoa base de dabs Masi DpCmnal prrconfQur& la% OpUDnw Iss ufildadea y el scftwsre basrco 6el clente w e un

S ~ N ~ C Dde D Sred

r Oracle91 Clent 9 0 1 1 1 degeslandcEatarpnse hbrsemmsdered

Figura 17.4. Elegimos el software que deseamos instalar

Configuracidn de Base de Datos Selecuone una base de datos que se ajuste a sus necesidades @

Us0 General hstsia U M bage de dstos confqurada prwlamte @madswfa Mo

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 emplear, pudiendo dejar el indicado por defecto o cambiarlo.

E Oracle Universal i n s t a l k Identifiacirjn de b s e s de b t o s ...

...

'

.

.

.

.

__

7

. . . . .'2-s ...

kill

ldentificacion de Bases de Datos -3s D J S S S J e O m s Or3.1e91j e denlificin : c n a u n i m ccn e ncmbre ce Dase de datos glabal, njrm31nien!e el 131manas ncmnre a,min,c Intrcc,ica el nomoie de base de Oatos gobal para esta base

de 3315s

,

.... - .. ._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

Figura 17.6. ldentificamos la base de datos que va a crearse

El paso siguiente serfi la elecci6n del conjunto de caracteres que se utilizara para 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 cualquier 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 distintas herramientas. Se iniciarfi el servidor HTTP de Oracle (una versi6n personalizada 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 tendremos 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.

Oracb9i Database 9.0.1.1.1

Requutos de Espaclo L401urnen C\Necesarios 1 U l G B Disponibies 28 42GB

+?@dancedReplication 9 0 1 1 1

Figura 17.7. Resumen previo al inicio del proceso de instalacion

'instairno Oracle Complete DSS Starter Daiatmse 9 0 1 0.1

Figura 17.8. Proceso de copia de archivos y configuracion

17. Acceso a Oracle desde V i s u a l Basic .NET

Herramientas de Configuracion

r3ce Oracle Intelligent agent

en curso pendiente

Figura 17.9. Configuracion de las herramientas instaladas

fl fl

v

Tennban&Creaci&tUeBasede~os Creaaon 6e ba3e de datos donica en curso

Figura 17.10. El asistente crea y configura la base de datos automaticamente sin intervencion nuestra

Terminada la creacion y Configuracion de la base de datos, veri aparecer una pequeiia ventana indic6ndole el nombre global, el SID y la contraseiia de las cuentas SYS y SYSTEM, dindole opci6n a modificarlas con el b o t h Gesti6n de Contraseiias. Pulse el boton Salir de esa ventana. Apareceri la de confirmacion de fin de instalacion del instalador universal de Oracle. Pulse de nuevo el b o t h Salir. Ya tiene Oracle instalado en su sistema.

Programacidn de bases de datos con Visual Basic .NET

___

I____

_____I

__

___-

I

-

-

_

_

__

I

---

~

I

_

~

_

I

_

_

_

I~

Una vez instalado el RDBMS, seguramente necesitari configurar parimetros de red, seguridad, etc. Oracle instala un gran n6mero de asistentes y herramientas, en contraposici6n a productos como SQL Server en 10s que pricticamente todas las operaciones se encuentran centralizadas. Todos ellos puede encontrarlos en la carpeta Oracle - HoraHomeSO de Inicio>Todos 10s programas. En la figura 17.11 puede ver algunos de esos elementos, concretamente la subcarpeta correspondiente a herramientas de configuraci6n y conversi6n.

PonerChute pius

Enterpire ManagementP ~ d s

'!Mhale

Enteipnse Manager Quick T O U ~ b

:W;inRAP

Integrated Management Tools

t

b

i ~

I

Acrobat Readri 5 ill

Figura 17.11. OracleSi instala multitud de herramientas y asistentes

Muchos de 10s aspectos relacionados con cuentas, perfiles y administracion de la base pueden realizarse con el Oracle Administration Assistant for Windows NT (vease figura 17.12). Abra el servidor, la rama Bases de datos y seleccione el SID de la base creada durante la instalaci6n. Haga clic sobre ella con el b o t h secundario del rat6n y elija la opci6n de conexi6n. A partir de ese momento podri acceder a las listas de usuarios, perfiles y administradores. €

__

-

-

__

___

Para poder conectar con una cierta base de datos Oracle, es indispensable conocer el nombre del servicio. Este se define en el momento de la creacion en el servidor, siendo necesaria tambien una definici6n en 10s clientes. Nuestra base de datos

17. Acceso a Oracle desde Visual Basic .NET

inicial, generada por el asistente, es reconocida en el propio servidor con el nombre de servicio L i b r o s

] M&va

__

proon

-- __ --

Yec

-

Eavontos

-

-

Ven_tana

-~

A&

08

Adrninistradwes de Bases de Datos del Sisterna Operc operadores de Bases de DatOr del Ststerna Operabbc

del Ststema O p r a b v o

Opeiadorer de Bases de Datos d d Sistema

Uruarios Externos del Sistma Operabvo

Roles Extemos d d Sisterna Operabuo Adnnnstradwes de Bases de D a b s del 9sten Operadores de Bases de D a b s del Sirtema 0

Figura 17.12. Consola de adrninistracion de Oracle

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 capitulos previos en 10s que se utilizaba la base de datos Oracle creada en el tercer capitulo. Puede crear su propio esquema y personalizarlo, si no quiere emplear 4ste.

Desde un sistema en el que se instale la plataforma Microsoft .NET, indispensable para ejecutar cualquier aplicaci6n creada con Visual Basic .NET, es posible acceder a multiples origenes de datos sin necesidades adicionales, ya que t a m b i h se instalan 10s MDAC. Esto significa que podemos usar una base de datos Access, una hoja de cdculo Excel o comunicarnos con un servidor SQL Server sin necesitar ningun software adicional. No es posible, sin embargo, una comunicacion directa con todos 10s productos RDBMS disponibles en el mercado, especialmente cuando son de diversos fabricantes y, por lo tanto, emplean distintos medios de comunicacih entre cliente y

Programacidn d e bases d e datos con Visual Basic .NET

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.

El software cliente debe instalarlo en la maquina de desarrollo tan solo si no es la misma en que este ejecutandose el RDBMS, caso en el que no es necesario. S i debe instalado en todos 10s ordenadores cliente donde vaya a utilizarse la aplicacion.

La instalaci6n de dicho software cliente se inicia con el mismo proceso explicad0 en el punto dedicado a la instalaci6n de Oracle9i, simplemente eligiendo la opci6n OracleSi Client en lugar de OracleSi Database en el paso del asistente que aparece en la figura 17.4. A1 finalizar el proceso, tendri en el ordenador 10s elementos necesarios para comunicarse con el RDBMS Oracle9i remoto.

Con algunos RDBMS, como es el caso de SQL Server, basta con instalar el software cliente para, desde una aplicacGn, conectar con una base de datos que se encuentra 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 Data 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 Configuracion de Red de Oracle que se instala como parte del software cliente. Este proceso se describi6 en el sexto capitulo, puede recurrir a 61 para recordarlo.

Ya tenemos en el equipo del cliente el software cliente instalado y el nombre del servicio definido. Para que nuestra aplicaci6n funcione, sin embargo, es necesario un elemento m6s: el proveedor ADO.NET Oracleclient.Este no forma parte de la instalaci6n estandar actual de la plataforma Microsoft .NET, a diferencia de Sqlclient y OleDb, por lo que debe ser instalado en cada sistema donde vaya a utilizarse para acceder a una base de datos Oracle. Podemos redistribuir el archivo oracle net .ms i como un m6dulo adicional que es necesario a1 instalar nuestra aplicacizn, de manera que este ahi disponible

17. Acceso a Oracle desde Visual Basic .NET

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 COnexi6n 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 puede 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 acceder a la base de datos mas usada desde el lenguaje de programaci6n m6s popular 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 necesitaremos emplear el objeto Transaction del proveedor adecuado tal y como se explica 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 asegura 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 adaptadores de datos y DataSet para actuar sobre dos tablas: una que contiene encabezados 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

pongamos por caso, es el de las lineas de detalle, se produce un fallo de alimentaci6n o una interrupci6n en las comunicaciones, de tal forma que se han enviado a1 servidor las lineas de detalle per0 a1 intentar el Update ( ) para enviar la cabecera se produce un error. En este momento en la base de datos existe una inconsistencia patente, dado que no es posible encontrar 10s datos del cliente y la factura a la que pertenecen las lineas. Para evitar esta situaci6n debe utilizarse una transacci6n. Esta se iniciaria antes de la prirnera actualizacih y terminaria tras la ultima. En ese ambito las operaciones se registran de forma temporal, confirmandose si todas se reciben satisfactoriamente o descartandose si se produce cualquier evento que impida mantener la integridad.

Una forma de asegurar la integridad de 10s datos en operaciones como la descrita, y que se dan constantemente en la mayoria de aplicaciones, consiste en emplear el sistema de transacciones de la propiedad base de datos. Para ello lo habitual es codificar procedimientos almacenados en la base de datos, de tal forma que las aplicaciones, cuando necesitan efectuar alguna operacih, invocan a1 procedimiento almacenado facilitandole 10s parametros necesarios, ocupandose 6ste de realizar la manipulacion de las tablas. El control de transacciones en la base de datos se efectuard con las sentencias propias del lenguaje de cada RDBMS, por ejemplo PL/SQL en Oracle o T-SQL en SQL Server. En el caso de T-SQL las sentencias a conocer son estas tres: BEGIN TRANSACTI ON, COMMIT TRANSACT ION, ROLLBACK TRANSACT I ON. La primera inicia una nueva transaccih, la segunda la confirma y la tercera la revoca. Dado que en SQL Server las transacciones pueden anidarse, cada una de estas sentencias ira seguida de un identificador propio. Suponga que quiere tener en la base de datos SQL Server creada como ejemplo en el tercer capitulo, un procedimiento almacenado a1 que facilitandole el c6digo de una editorial elimine todos 10s libros que le pertenecen y la propia editorial. Esto requiere dos sentencias DELETE y, para evitar que la operacih pudiese interrumpirse entre ellas, las introducimos en una transacci6n. El procedimiento almacenado podria ser el siguiente:

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

sentencias anteriores quedan canceladas aunque, en apariencia, parezca que se ejecutan. Puede comprobarlo ejecutando el procedimiento desde el Analizador de consultas SQL de SQL Server, como se ha hecho en la figura 18.1. Fijese en el panel de resultados, donde se indica el numero de filas afectadas en ambas tablas. Si las abre, sin embargo, cornprobar5 que no se ha eliminado fila alguna. Desde una aplicacion Visual Basic .NET podriamos ejecutar este procedimiento almacenado, dejando el control de las transacciones directamente en manos del servidor de datos.

Y

> Cwndetado el proceso wr lotes de la conwlta

INSPRON (8 0) INSPIRON$ranorca (52) L h o s

0 00 00

0 Rlas

i n 1, Col 28

Figura 18.1. Aparentemente el procedimiento almacenado ha eliminado filas en ambas tablas

.........____....... _.__ . ......._ ~ . _ _..-.._t.,_...I_._ .^__... . ......._..._ ~

_

~

_

^

_

Las transacciones tambien pueden ser controladas de manera explicita desde el codigo de un programa Visual Basic .NET, empleando para ello el objeto Trans action especifico del proveedor que vayamos a utilizar para acceder a1 origen de datos: S q l T ran sa ct ion, 01e DbTran saction, 0ra cleTran sa cti on u Odb cTransaction.

Las cuatro clases mencionadas tienen en comun la implementacibn de la interfaz IDbTransaction.Esta cuenta tan solo con cuatro miembros, dos propiedades y

dos m6todos:

18. Control de transacciones

0

Connection: Establece el vinculo entre este objeto Transaction y un objet0 Connection. IsolationLevel: Fija el nivel de aislamiento entre esta transacci6n y las demds que pudieran existir en el RDBMS sobre 10s mismos elementos.

0

commit ( ) : Confirma la transacci6n.

0

Rollback

( ) : Revoca

la transacci6n.

No necesitamos mds para controlar desde un metodo Visual Basic un proceso similar a1 explicado en el punto previo a mod0 de ejemplo.

Para crear una transaccion asociada a una cierta conexion, como puede deducirse 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, implementado en el objeto Connection de cada proveedor. Ese objeto tiene que asociarse tambien con cada uno de 10s comandos que vayan 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 operaciones de actualizacion, para confirmar o revocar la transaccion y, por tanto, todas las operaciones ejecutadas durante su tiempo de vida.

Veamos en la practica como crear y controlar una transaccion desde un programa Visual Basic .NET, empleando para ello el proveedor de SQL Server. El metodo BeginTransaction ( ) de Sqlconnection, asi como 10s metodos Commit ( ) y Rollback ( ) de SqlTransaction, en realidad hacen us0 de la gestion de transacciones propia del RDBMS, mediante las sentencias comentadas anteriormente. Comenzaremos insertando en un formulario 10s componentes que pueden verse en la figura 18.2. Hemos arrastrado la tabla Libros de la base de datos SQL Server desde el Explorador de servidores hasta el diseiiador, utilizando el menu emergente de SqlDataAdapterl para generar el conjunto de datos DsLibrosl. Los principales elementos de interfaz son un cuadro de texto para introducir el c6digo de una editorial, un b o t h para seleccionar las filas, que aparecerdn en el DataGrid que hay debajo, y un segundo boton que eliminaria esas filas del origen de datos.

Prograrnacidn de bases de datos con Visual Basic .NET

Dates

8

Format0

-

Herramlentas

-

p Debug

'3@*33-. 1 :

x

Figura 18.2. DiseAo del formulario

En principio no existe ningun vinculo entre 10s elementos de interfaz y 10s componentes de acceso a datos, vinculo que se establecer6 a1 pulsar el b o t h Seleccionar. Este ejecuta el c6digo siguiente: .(ByVal s e n d e r As System.Ob]ect, Priva ByVal e As Systern.EventArgs) Handles btnSelecc1onar.Click ~

SqlDataAdapterl. Fill (DsLibrosl, "Libros")

Dim Vista As DataView = New DataView(DsLibrosl.Libros, "Editorial=" tbCodigoEditoria1. Text, "Titulo", ~

DataViewRowState.CurrentRows)

&

~

18. Control de transacciones

I g L i b r o s . Datasource = V i s t a E n d Sub

Como puede ver, llenamos el DataSet usando el adaptador de texto, creando a continuaci6n una vista en la que aparezcan s610 10s titulos de la editorial cuyo c6digo se haya introducido en el TextBox. Finalmente, enlazamos esa vista con el DataGrid, que mostraria las filas que van a eliminarse en caso de que pulsemos el b o t h Eliminar. El proceso de eliminacih de las filas es sencillo, basta con recorrer la vista e ir llamando a1 metodo Delete ( ) de cada uno de 10s elementos y llamar a1 metodo Update ( ) del correspondiente adaptador de datos. Eso es, bisicamente, lo que vamos a hacer a1 pulsar el b o t h Eliminar, per0 delimitando la operacion dentro de una transacci6n y confirmtindola o revoc6ndola segun lo que responda el usuario a una ~ l t i m apregunta de confirmacibn. El c6digo asociado a1 evento C l i c k del boton seria el siguiente: -

P r i v a t e Sub b t n E l i m i n a r ~ C l i c k ( B y V a 1s e n d e r As S y s t e r n . O b ] e c t , 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

~

Dim Vista As DataVlew = C T y p e ( d g L i b r o s . D a t a S o u r c e , Dataview) Dim T r a ri s a c c 1on As I DbT r a n s act i on

While V i s t d . C o u n t

> 0

Virta(O).Delete() End W h i l e

sq

De

S g 1[lat a A d a p t e r 1 . Upd a t e ( V I s t a . Tab L e )

"Trar,sacciones", MessageBoxButtons. YesNo) D i a l o g R e s u l t . Yes T h e n 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

SqlDataAdapterl.F i l l ( D s L t b r o s l , " L i b r o s " )

Sqlconnectionl .Close i ) End Sub

Obtenemos una referencia a la vista que se cre6 previamente para vincularla a1 D a t a G r i d , efectuando la conversi6n de tipo necesaria. Luego abrimos la conexi6n e iniciamos la transaccibn, borramos las filas, asociamos la transacci6n con el D e 1 e t e C o m m a n d del adaptador e invocamos al metodo U p d a t e ( ) de kste. En ese momento las filas desaparecerh del D a t a G r i d e, incluso, no podria acceder a

ellas desde otra aplicaci6n o desde el Administrador corporativo de SQL Server. Se encuentran bloqueadas a la espera de que la transacci6n se confirme o descarte. Que llamemos a1 metodo commit ( ) o R o l l b a c k ( ) depender6 de la respuesta del usuario. Independientemente de c u d se ejecute, terminamos refrescando la informacih del D a t a S e t y cerrando la conexi6n. Si se ha confirmado, el D a t a G r i d permanecera vacio ya que las filas se habran borrado, mientras que de revocarse el D a t a G r i d volver6 a mostrar las mismas filas.

b

17 11 13 14

4 15 12 10

3

0 471 37523 3 84 415 1255 8 84 415 1202 7 84 415 1132 2 84 415 1230 6 84 415 1291 4 84 415 1324 4 84 41 5 1145 4 84 41 5 1230 2 84 415 1261 2 84 415 1351 1 84 415 1392 3 84 41 5 1376 7 8441511365

Assembly Language Step by Ste Guia piactica para umarios de D Guia piactica para umaiios de E Guia ptactica para U S U ~ ~ I Ode S r Guia practica para usuarios deVi Guia practica paia usuarios de VI Guia ptactl~apara usuatosJEW lntroduccion a la programacion Manual avanzado Excel 2002 Progiamacioncon Delphi 6 y Kyli ProgiamacionconVirual Basic Piograrnacion conVisual C# NE PiogramacionconVisual Studio

SQLServer2000

Jeff Duntemann Francisco Chaite Francisco Charte/ Francisco Charte Francisco Charte Fiancisco Charte F ~ a n c ~ Charle co Francisco Charte Francisco Charte Francisco Charte Francisco Charte Fiancisco Chaite Francisco Chartet Francisco Charte

1 1 1 1 1 1 1 1 1 1 1 1 1 1

60 5 1052 1052 1052 10 75 1052 1075 24 04 21 04 37 26 33 39 40 10 75

Figura 18.3. El programa mostrando la lista de filas que van a eliminarse

De manera an6loga podriamos controlar con transacciones explicitas cualquier otra situacibn, generalmente en la que se encontrasen implicadas dos o m6s tablas que deban mantener una integridad referencial, ya que en este caso hubiese bastado con pedir la confirmaci6n antes de eliminar las filas y actualizar con el adaptador de datos, sin necesidad de usar una transacci6n.

..* A

El empleo de transacciones asegura la integridad de 10s datos, s e g ~ ha n podido verse en el capitulo previo, per0 no resuelve por si solo 10s problemas de concurrencia que pueden presentarse. Por defecto, ADO.NET utiliza una politica de bloqueos optimista, lo cual significa que 10s datos se recuperan en un Data S e t per0 cualquier otro usuario puede acceder a ellos de manera simultAnea. Puede darse el caso, por tanto, de que varias aplicaciones cliente, generalmente en distintos ordenadores distantes entre si, e s t h mostrando la misma informacidn e, incluso, permitan a1 usuario modificarlos. iQu6 ocurre si un usuario modifica o elimina alguna de esas filas y, a continuacibn, otro usuario intenta modificar esa fila, ya cambiada o inexistente? Por defecto se genera una excepcidn, impidiendo a1 segundo usuario hacer cambios en una fila cuyo estado ha cambiado desde que la recuperd en el Data S e t. El objetivo de este capitulo es mostrarle, con un ejemplo, cdmo responder a esta situacidn para poder resolverla de forma satisfactoria, sin perder directamente 10s cambios que haya efectuado el usuario per0 sin escribir tampoco 10s cambios sobre el origen perdiendo la informacibn que otro cliente haya introducido.

e bloqueo y actualizacion A la hora de codificar una aplicacidn en la que van a obtenerse datos que, posteriormente, deben ser actualizados, hay que elegir una politica de bloqueo y de

19. Resolucion de problemas de concurrencia

actualizacion. Bisicamente existen dos opciones: bloqueo optimista y bloqueo pesimista. Hay una tercera, aunque generalmente no es aceptable en la mayoria de aplicaciones, a la que se hace referencia como el u'ltimo gana. El bloqueo pesimista consiste en bloquear las filas que presumiblemente van a actualizarse desde el mismo momento en que leen de la base de datos, lo cual significa que ningun otro cliente puede tener acceso a ellas hasta que el proceso de modificacibn y actualizaci6n termine. Es una politica que requiere mantener una conexi6n abierta con el servidor todo el tiempo que dure ese proceso, porque de lo contrario no podria mantenerse el bloqueo sobre las filas. Sus inconvenientes son muchos, siendo el m6s importante que s610 un usuario puede tener acceso a las filas en cada momento, lo cual no suele ser aceptable en aplicaciones que se ejecutan en multitud de clientes contra una misma base de datos.

En ADO.NET no existe la opcion de usar una politica de bloqueo pesimista ya que, por naturaleza, se opera sin una conexion persistente con el servidor. Es posible simular ese comportamiento, no obstante, iniciando una transaccion antes de recuperar las filas y manteniendola hasta despues de la actualizacion.

La politica de bloqueo optimista s610 bloquea las filas que van a ser modificadas 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 filas, 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 base 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 excepto 10s del ultimo en enviarlos a1 RDBMS. Como se decia antes, suele ser una opci6n inaceptable en la mayoria de 10s casos.

Cuando se crea un adaptador de datos, ya sea directamente a1 arrastrar una tabla desde el Explorador de servidores o tal y como se describi6 en 10s capitulos de

Prograrnacidn de bases de datos con Visual Basic .NET

la segunda parte, se utiliza un objeto CommandBuilder que se encarga de generar las sentencias de actualizacih y eliminaci6n de filas. Estas contienen todas las condiciones necesarias para garantizar el bloqueo optimista, comprobando que 10s valores que tenia la fila originalmente son 10s que tiene en el momento de la actualizacih, no habihdose modificado ninguno de ellos porque se haya producido otra actualizacih en paralelo. En el momento en que se llama a1 mktodo Update ( ) de un adaptador de datos, facilitando como pardmetro la tabla que tiene las filas modificadas, se recorren las filas una a una y se ejecuta una sentencia UPDATE cada vez que se encuentre una cuyo estado indique que ha sufrido cambios. El RDBMS ejecuta la actualizacion y confirma a ADO.NET el &xitoo el fracaso, generindose a continuacih el evento Rowupdated del adaptador de datos. El segundo parimetro que acompaiia a ese evento contiene un indicador de estado, mediante el cual puede saberse si se ha efectuado la actualizacih o producido un error; un mensaje de error, una referencia a la fila afectada, otra a1 comando ejecutado, etc. En caso de que la propiedad RecordsAf fected sea cero y Status contenga el error Updatestatus. ErrorOcurred, sabremos que se ha producido un error que ha impedido la actualizacih de la fila. Raz6n: 10s valores DataRowversion. Original de la fila que tenemos en el programa no coinciden con 10s valores que existen en la base de datos. Si no modificamos el valor de la propiedad Status,y dejamos que la ejecucidn continue, se produciri una excepcih. Podemos notificar el problema a1 usuario y modificar dicha propiedad, impidiendo la generaci6n de la excepci6n.

-

~

I_

_

_

Veamos c6mo aprovechar el evento RowUpda ted para ofrecer informacih sobre 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 (dsLibrosl, "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

P r i v a t e Sub btnActualizarpClick ( B y V a l s e n d e r As System.Ob]ect, B y V a l e As System.EventArqs) Handles btnActualizar.Click

19. Resolucidn de problemas de concurrencia

s1.L

SqlDataAdapterl. Fill (DsLibrosl, "Libros") End Sub

nrchivo

Edition

Yer

Proyecto

enmar

- _ t1rto-

Depurar

Datos

Herrarmentas

I/

Ventana

Aygda

1

-.-

-

-

__ I

Figura 19.1. Aspect0 del formulario con la cuadricula y el boton

Si no hemos cambiado ning6n dato, 10s datos de la cuadricula mostrarin cambios que otros clientes puedan haber efectuado, per0 no se desencadenarfi en ning6n momento el evento RowUpdated.Esto tan s610 ocurriri una vez por cada fila modificada, ejecutfindose el c6digo siguiente: Pr

lDat ed(ByVa1 serider A s O b j e c t , ByVal e A s System.Data.SqlClient.SqlRowUpdatedEventArgs) Handles SqlDataAdapter1.RowUpdated ~

I f e.Status

=

UpdateStatus.ErrorsOccurred Then

MessageBox.Show(e.Errors.Message & vbCrLf & e. Row. Item("Autor", DataRowVersion. Original) & vbCrLf & e.Row. Item("Autor", DataRowVersion.Current) )

-

Programacidn de bases de datos con V i s u a l Basic .NET

e.Status End I f End Sub

=

UpdateStatus.SKipCurrentRow

Como puede ver, comprobamos si el estado indica la existencia de un error, caso en el que mostramos por la consola el mensaje, el valor original que tenia la fila y el que nosotros pretendiamos darle en una de las columnas, que es la que pretendemos modificar a mod0 de ejemplo. Por ultimo asignamos el valor Updates tat u s . SkipCurrentRow a la propiedad Status, impidiendo la generaci6n de la excepci6n DBConcurrencyException a1 tiempo que se ignoran 10s cambios de la fila. Si ejecuta el programa, efectcia cualquier cambio y pulsa el b o t h Actualizar todo ir6 bien. Para provocar un error tendr6 que ejecutar dos copias del programa y cambiar la misma fila, o bien hacer alguna modificaci6n desde el Administrador corporativo. En esos casos nos encontraremos con una situaci6n como la de la figura 19.2. Observe el mensaje de error.

1 89311534 1 84 415 1136 5 84 415 1324 4 84 4151332 9 84 415 1376 7 84 415 1351 1 84 415 1290 6 84 415 1231 4 84 41 5 1261 2 84 415 1255 8 84 415 1230 2 84 415 1202 7 8441511322 84 41 5 1145 4

User Inteilace Design lor Programmers

SOLserver 2000 Guia ptactica para usuaiiosJBuilder 7 PiogramacionconVisual C# NET Ptogiamacion con Visual Studio NET ProgramacionconVisual Basic NET Gum practica paia U Q U ~ ~ I OdeVisual S Basic Guia practica paia wuarios de Visual Studio Piogiamacion con Delphi 6 y Kylix Guia piactica pata usuams de Delphi 6 Manual avanzado Excel 2002 Gum practica paia U S U ~ ~ ~deO Excel S 2002

JoelSpolsky Francisco Charte Francisco Charle Francisco Charle Fiancisco Chaite/Jorge Seriano Francisco Chaite Francisco Charte Francisco Charle

GuiapracticapatausuariordeKylix

lntioduccion a la piogiamacion

Figura 19.2. Al actualizar se ha encontrado un problerna de concurrencia

El ejemplo anterior es titil porque notifica a1 usuario que ha surgido un problema de concurrencia y, por lo tanto, 10s cambios que ha efectuado se perderdn. No obstante, se le obliga a, tras haber actualizado 10s datos que tenia en el DataGrid,

19. Resolucidn d e problemas d e concurrencia

volver a introducirlos si se quiere ejecutar la modificacih. Podemos mejorar este comportamiento dando 10s pasos siguientes en caso de que se genere un error: Obtenci6n en un nuevo D a t a set con la informacion actual que hay en la base de datos. Informar a1 usuario del valor actual, el que habia originalmente y el que ha introducido el, preguntfindole si quiere sobrescribir la informacion que hay actualmente en la base de datos. En caso afirmativo, se utilizaria el metodo Merge ( ) del conjunto de datos original para unirlo con el que acaba de recuperarse, facilitando como segundo parfimetro el valor True para preservar 10s cambios que haya hecho el usuario. Nueva llamada a1 metodo Update ( ) del adaptador para provocar la nueva actualizacion. Tomando como base el ejemplo del punto anterior, modifique el metodo asociado a1 evento Rowupdate para que, en lugar de mostrar el mensaje de error, invoque a1 siguiente metodo Resolucion ( ) facilitando como pardmetro e. Row, es decir, la fila que ha provocado el error.

DatosActuale5 .Libras.FindByIDLibro( F l l a . Itern("IDL1bro") )

Dim M e n s a j e As String = String.Forrnat("Va1or actual='{O]', " & "Valor original='{l}', Valor propuesto='t2}'", FilaOriginal .Autor, Fils. Item( " A i i t ~ r " , DataRowVerslon.Orlglria1), Fila. Item("Autor", DataRowVersion.Current 1 ~

~

~

MessaqeBoxButtons.YesNo)

=

scribir cambios?", 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 metodo 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 podria 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 Update ( ) . 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/

l L

Valor actual='Francisco Charte Ojeda', Valor original='FranciscoCharte Ortega', Valor propuesto='Francisco Charte'

/I

W

I1

Figura 19.3. Mensaje d e notificacion y consulta del programa al encontrar un error d e concurrencia

Este mecanismo de control de concurrencia es el adecuado cuando se opera con componentes DataSet y controles vinculados a el. Si estamos usando otros medios, como DataReader 0 ejecucion directa de consultas, no contaremos con 10s comandos de bloqueo optimista generados por 10s asistentes, teniendo que controlar nosotros 10s problemas que pudiesen surgir. En la documentacion electronica de Visual Basic .NET podra encontrar algunas alternativas, como la insercion en todas las tablas de una columna que mantenga una referencia temporal de cuando se modifico por ultima vez la fila. Al leerla se cuenta con esa referencia, y a1 actualizar habria que cambiarla siempre con la condicion de que no se haya modificado porque ello significaria que otro usuario la ha actualizado.

f

..*..,..,*' ..*.~ .,. .'.,"~.. .. ,*:

a;:?

.

. . x

'~._.

' ~.