UNIVERSIDAD AUTONOMA METROPOLITANA
UNIDAD:
DIVISION:
CARRERA:
MATERIA:
TITULO:
FECHA:
ALUMNO:
MATRICULA:
ASESOR:
IZTAPALAPA
CIENCIAS BASICAS E INGENIERIA
INGENIERIA ELECTRONICA
PROYECTO DE INGENIERIA ELECTRONICA I
Y II
INTERFACES DE PROGRAMACION DE APLICACIONES PARA CONEXION A BASES DE DATOS.
ODBC, UNA API DE VISUAL BASIC Y JDBC.
MARZO DE 1999
GARCIA CUEVAS JUVENAL
89327433
Interfaces de Programación de
Aalicaciones
aara
conexión a bases de datos
ODBC, una
API de
Visual Basic
y JDBC
Juvenal Garcia Cuevas
División de Ciencias Básicas e Ingeniería Universidad Autónoma Metropolitana Unidad lztapalapa
1
Revisión
Interfaces de Programación de Aplicaciones para conexión
a bases de datos
ODBC, una API de Visual Basicy JDBC
Juvenal Garcia Cuevas
El contenido de ésta obra corresponde a la
documentación del proyecto de Ingeniería Electrónica I y II llevado a término por el autor, de acuerdo
con el plan de estudios vigente de la Universidad Autónoma Metropolitana
Impreso en México
Esta obra se terminó de imprimir en Marro de 1999
en las instalaciones del Edificio T de Ciencias Básicas e Ingeniería de la Universidad Autónoma Metropolitana Unidad Iztapalapa,
Av. Michoadn y la Purísima
Col. Vicentina
Delegación lztapalapa 09340 México, D.F.
Prólogo
Se ha dicho que la necesidad es madre de la inventiva, y se ha dicho bien. Antes de que yo siquiera pensara en terminar mis estudios en la UAM Iztapalapa, el profesor Luis Castro me invitó a participar en un proyecto avalado por la universidad. Este consistía en el desarrollo de sistemas para el corporativo PEMEX REFINACION, con sede en el puerto de Veracruz. Para mí era una excelente oportunidad de andar nuevamente en el camino de la Ingeniería de Software y de probar las habilidades adquiridas durante el ciclo universitario, pues antes de ello trabaje exclusivamente en el campo de las redes computacionales.
Durante las primeras cinco semanas de desarrollo para el convenio PEMEX-UAM, hubo el requisito de acceso a bases de datos por ODBC. En la primera semana me dediqué a investigar sobre el tema, desde saber que significaba ODBC hasta la manera de utilizarlo. ODBC cuenta con un conjunto específico de funciones para realizar las tareas de conexión y de ejecuci6n de
instrucciones de SQL, pero eso no es todo, algunas de las funciones requieren de una gran cantidad de argumentos, cada uno con un objetivo especial, inclusive se utilizan apuntadores.
Esto no habría significado gran cosa de haberse usado el lenguaje C, pero el problema radicaba en que la herramienta escogida para el desarrollo era Visual Basic y se habían descartado
los
mecanismos de acceso a datos por RDO y DA0 por excederse en los tiempos de respuesta. Finalmente me dedique a experimentar el uso de las funciones de ODBC dentro de Visual Basic. Elaboré infinidad de pequehas pruebas para cada una de las funciones que a mi juicio serían lasmás
útiles a nuestras necesidades. Poco a poco, las pruebas que había elaborado me revelaron patrones acentuados en cuanto a la forma de disponer de las funciones de ODBC y convine en aprovechar tal comportamiento para el beneficio general, creando una lnterfaz de Programación de Visual Basic basada en ODBC. Los resultados obtenidos fueron satisfactorios.Posterior al desarrollo en Visual Basic, surgió un nuevo desarrollo para Web, al igual con miras a consultar una base de datos, de aquí mi conocimiento sobre JDBC, pues en 6sa ocasión la
plataforma fue Java.
Contenido
Prólogo
Introducción
PARTE
I.
ODBC
I
Aspectos generales de ODBC
1.1
La Conectividad a Bases de Datos Abiertas
1.2 Los
Drivers
y
el Driver Manager de ODBC
Porqué usar ODBC
El Driver Manager de ODBC ODBC Desktop Database Drivers
Registrando una fuente de datos en el código
1.3
Registro de una fuente de datos
2
La API de ODBC
2.1
El enfoque Cliente/Servidor
2.2
Objetos de Datos Remotos
o
llamadas a funciones de la
API
de ODBC
2.3
Codificación directa a la API de ODBC
Arquitectura del modelo de codificación directa
2.4
La librería de
enlace dinámico: ODBC32.DLL
3 Conexión ODBC a bases de datos
3.1
Primero: Se requiere un handle de ambiente
3.2
Segundo: Se requiere un handle de conexión
3.3
Tercero: Se procede a la conexión
La función SQLAllocEnv ( )
La función SQLAllocConnect ( )
Requisitos para la conexión
Creando el nombre de fuente de datos (DSN) de ODBC Tres maneras de culminar la conexión
La función SQLConnect ( )
La función SQLDisconnect ( )
La función SQLFreeConnect ( )
La función SQLFreeEnv ( )
3.4
Ultimo: Se liberan los recursos usados
3.5
Formato básico de una aplicación ODBC
¡x
xv
i
3
9
9 11 12 13 14
I S
15 15 16 17 17 18 18 18 19 21 21 22 23 23
3.6
Conexiones múltiples
y
manejo de errores
Manejo de errores
La función SQLError ( )
Recuperando mensajes de error Mensajes de error de ODBC Formato del mensaje de error
Los tipos de datos
3.7
Los códigos de retorno
y
los tipos de datos
4 El manejo de instrucciones de SQL
4.1
Lo primordial: El handle de
sentencia
4.2
SQLExecDirect: Ejecutar instrucciones de SQL
4.3
SQLBindCol: Asociando variables
y
columnas
La función SQLAllocStmt ( )
La función SQLExecDirect ( )
El manejo de variables de Visual Basic y SQLBindCol
Usando cadenas de Visual Basic con SQLBindCol Usando memoria global: funciones de la WinAPI
La función SQLBindCol ( )
4.4
SQLFetch: Navegar por los resultados
La función SQLFetch ( )
4.5
SQLGetData: Recuperando la información por columnas
La función SQLGetData ( )
4.6
Esquema general de procesamiento
de instrucciones de SQL
5 Resumen de funciones de ODBC
5.1
Niveles de conformidad
5.2
Funciones
y
niveles de conformidad
Funciones del núcleo Funciones del Nivel 1 Funciones del Nivel 2 Para más información
PARTE II. La biblioteca de funciones
6 Sobre la biblioteca de funciones
6.1
Objetivo
y
alcance de las
funciones
6.2
Tipos de Datos Abstractos utilizados
El tipo Base de Datos El tipo Registro de SQL El tipo Consulta de SQL
Definiciones de constantes para códigos de retorno
6.3
Llamadas a la
API
de ODBC involucradas
7 Conexion.bas: La biblioteca de funciones
7.1
La función ConectarBD
7.2
La función ConectarBD2
7.3
La función HacerConsultaSQL
7.4
La función HacerEscDirectaSQL
La función HacerEscrituraSQL
7.5
La función EjecutarSQL
7.6
Las funciones de navegación de resultados
7.7
La función CerrarInstrucSQL
7.8
La función DesconectarBD
7.9
La función ErroresNativos
7.10
Las funciones privadas
La función privada DescErrorODBC La función privada RepUltimaConsulta
8 Uso de las funciones
8.1
Un ejemplo sencillo
8.2
Esquema de uso de las funciones
8,3
Nuevamente el manejo de errores
PARTE 111. JDBC
9 Introducción a JDBC
9.1
Que es JDBC
Qué es lo que hace JDBC
JDBC es una API de bajo nivel y es la base de APIs de alto nivel
9.2
JDBC versus ODBC
y
otras
APIs
9.3
La arquitectura de JDBC
Acceso de la API JDBC a las bases de datos
10 Conexión JDBC a bases
de
datos
10.1
Las clases del paquete java.sq1
Interfaces de JDBC Objetos de JDBC Excepciones de JDBC
La interfaz Driver El objeto DriverManager
Sobre los URLs de JDBC
10.2
Conexión con la base de datos
10.3
Creación
y
ejecución de sentencias de SQL
La interfaz Connection La interfaz Statement El objeto Resultset
Un ejemplo simple de ejecucibn de instrucciones de SQL
10.4 Las herramientas de JDK
javac-El compilador de Java
java-El Intkrprete de Java
Compilando y corriendo un ejemplo
Para más infomacibn
PARTE IV. Apéndices
A
Declaración de las funciones de la API de ODBC.
B Conexion.bas: Código de las funciones.
Bibliografía
lndice
99 1
O0
1
O0
1 o1
102
103
104
105 106 1 o9
111
113
133
157
159
Introducción
La conexión a bases de datos abiertas es uno de los temas más importantes en la industria de la computación. La necesidad de comunicación con los distintos sistemas de bases de datos para el acopio de información ha dado paso a uno de los estándares más revolucionarios en el terreno de la informática: La Open Database Connectivity u ODBC, la cual es ahora una de las herramientas más utilizadas en el desarrollo de aplicaciones que necesitan el acceso a múltiples bases de datos con un alto grado de eficiencia y confiabilidad. Más recientemente, ha visto la luz el similar de ODBC para el desarrollo de aplicaciones para acceso a bases de datos en el Web: La Java Database Connectivity o JDBC, que ofrece un cúmulo de posibilidades y que muchas firmas de software han comenzado a explotar.
Este trabajo trata de la conexión a las bases de datos utilizando la API de ODBC y las clases de JDBC. Se presenta tambikn una API de Visual Basic basada en ODBC. La API (Application
Programming Interface, lnterfaz de programacidn de aplicaciones) de ODBC, es el conjunto de funciones de la Librería de Enlace D i n h i c o ODBC32.DLL para la conexión a bases de datos
abiertas (Open Database Connectivity, Conectividad a bases de datos abiertas) mediante la cual es posible acceder a cualquier base de datos sin importar cual sea. La conexión a bases de datos desde Java se logra con JDBC (Java Database Connectivity, Conectividad a bases de datos de
Java), la cual es tambien proporcionada por las clases recientemente incorporadas al JDK en su versi6n 1 .I por Sun Microsystems.
La información contenida aquí se divide en tres partes. En la primera se realiza un breve estudio de ODBC y como es que permite hacer conexiones a bases de datos múltiples, se hace tambi6n una descripcidn de la API y de las llamadas a 6sta para usar sus recursos. En la segunda parte se estudian las funciones basadas en ODBC construidas en Visual Basic y la forma de explotarlas. Finalmente, en la tercera parte, se revisa la forma de usar la interfaz de JDBC para la conexión a bases de datos desde Java dentro de una intranet. o desde la Internet.
PARTE
I.
ODBC
O
Aspectos generales de ODBC
O
La
API de ODBC
O
Conexión ODBC a bases de datos
O
El manejo de instrucciones de SQL
1
Aspectos
generales de ODBC
Para hacer uso de la conectividad a bases de datos abiertas, es necesario contar con los drivers adecuados de ODBC de las bases de datos que se deseen accesar, as¡ como del administrador de fuentes de datos de ODBC para disponer de las bases de datos. En &te capítulo se da una introducción sobre ODBC y se describen los controladores o Drivers que componen la interfaz de ODBC y el uso del administrador de fuentes de datos ODBC.
1.1
La Conectividad a Bases de Datos Abiertas
ODBC son las siglas para Open Database Connectivity (conexión a bases de datos abiertas), la cual es una especificación de Microsoft. ODBC fue creado por el SQL Access Group y su primera liberación fue en Septiembre de 1992. AI mismo tiempo Microsoft Windows fue el primero en proporcionar un producto ODBC, ahora ya existen versiones para plataformas UNIX, OS/2, y Macintosh.
ODBC es un estandar o una lnterfaz de Programacidn de Aplicaciones (API, Application Programming Interface) para el acceso a las bases de datos. Esta API es independiente de cualquier sistema manejador de bases de datos o sistema operativo; la API de ODBC es
independiente del lenguaje de programación. La API de ODBC esta basada en las especificaciones CLI de X/Open e ISO/IEC. ODBC 3.0 implementa ambas especificaciones-las versiones
anteriores de ODBC se basaron en las versiones preliminares de 6stas especificaciones pero no las implementaron-y adicionaron características requeridas por
los
desarrolladores de aplicaciones de bases de datos basadas en pantallas, tales como los cursores navegables.AI usar llamadas a funciones ODBC en un programa se pueden acceder a archivos de varias y diferentes bases de datos, incluyendo Access, dBase, Excel y Texto. AdemAs del software de
4
ODBC, es necesario un controlador o driver para cada base de datos que es accesada. Microsoft es quien principalmente propone y proporciona el soporte a la programaci6n con ODBC.
ODBC está basado y estrechamente alineado al Open Group Standard Structured Query Language (SQL) Call-Level Interface (CLI). Esto permite a los programas usar consultas SQL que accesarán a las bases de datos sin tener que preocuparse de las interfaces propietarias de las mismas. ODBC maneja las consultas SQL y las convierte en consultas interpretables por cada sistema de base de datos individual.
Porqué usar ODBC
ODBC proporciona una manera uniforme de definir fuentes de datos y sus respectivos metodos de acceso a las mismas. ODBC está disefiado basándose en SQL y las bases de datos relacionales. La especificación de ODBC define llamadas de nivel bajo a la API que cualquier aplicaci6n puede usar para consultar una base de datos. AI escribir llamadas a la API una aplicaci6n cualquiera puede accesar fuentes de datos heterogeneas con s610 un código fuente.
ODBC permite a las aplicaciones el acceso a los datos en una forma común, la cual les da a las aplicaciones portabilidad, agiliza su desarrollo y facilita la curva de aprendizaje de los desarrolladores cuando se requieren múltiples fuentes de datos. ODBC está reconocido como un estándar en el acceso de datos.
1.2 Los Drivers
y el Driver Manager de ODBC
ODBC está diseñado para un máxima interoperabilidad, esto es, la habilidad de una aplicaci6n
para accesar diferentes sistemas manejadores de bases de datos (DBMS) con el mismo cbdigo fuente. Las aplicaciones de bases de datos llaman a las funciones en la interfaz de ODBC, la cual está implantada en m6dulos propietarios de la base de datos específica llamados controladores (en ingles Drivers). El uso de controladores aísla a las aplicaciones de las llamadas específicas de una base de datos en la misma forma en que los controladores de las impresoras aislan a los programas procesadores de textos de los comandos específicos de las impresoras. Como los controladores son cargados en tiempo de ejecucidn, un usuario
s610
tiene que agregar un nuevo controlador para accesar a un nuevo DBMS; no es necesario recompilar o reenlazar la aplicaci6n.Las funciones en la API de ODBC son implementadas por los desarrolladores de los controladores de DBMS específicos. Las aplicaciones llaman a las funciones en esos controladores para el acceso a datos en una forma independiente al DBMS. Un administrador de controladores maneja la comunicaci6n entre las aplicaciones y los controladores.
5
Para ayudar a los desarrolladores de controladores y aplicaciones, Microsoft ofrece el Kit para Desarrollo de Software ODBC (SDK ODBC) para computadoras con Windows NT Server, Windows NT Workstation, y Windows 95, el cual proporciona el Driver Manager, el instalador de DLL, herramientas para pruebas, y aplicaciones de ejemplo.
Es importante entender que ODBC este disefiado para explotar las capacidades de las bases de datos, no para sustituirlas. Por esto,
los
escritores de aplicaciones no deben esperar que usando ODBC repentinamente transformart!tn una simple base de datos en un sistema completo de base de datos relacional. Tampoco hay escritores de controladores que implementen funcionalidades que no hay en las bases de datos conocidas. Una excepcibn a esto es que los desarrolladores quienes escriben controladores que directamente accesan archivos de datos (tales como los datos en un archivo Xbase) requieren escribir un sistema de base de datos que soporte la funcionalidad mínima de SQL. Otra excepcibn es el ODBC SDK, el cual proporciona una librería que simula los cursores navegables para controladores que implementen un cierto nivel de funcionalidad. Las aplicaciones que usan ODBC son responsables de cualquier funcionalidad que implique bases de datos cruzadas. Por ejemplo, ODBC no es un sistema de uniones heterogéneas, ni es unprocesador de transacciones distribuidas. Sin embargo, como es independiente del DBMS, puede ser usado para construir tales herramientas de bases de datos cruzadas.
El Driver Manager de ODBC
El administrador de controladores de ODBC u ODBC Driver Manager, proporciona la interfaz entre el host y el back-end del controlador de la fuente de datos. El administrador de controladores es responsable de:
Cargar el controlador de la base de datos remota especificado por la entrada de nombre de fuente de datos.
lnicializar la interfaz.
Proporcionar puntos de entrada a
los
correspondientes del controlador. Validar paremetros y manejar la serializacibn de funciones de ODBC.El administrador de controladores de ODBC es una Librería de Enlace Dinemico (dynamic link library, DLL)-en particular se trata del archivo ODBC32.DLL-que puede hacer de interfaz con un back-end (servidor) de un sistema de base de datos o un tipo específico de archivo implementado como una base de datos.
Hay otros controladores especiales para cada tipo de base de datos, que conectan al Microsoft SQL Server, a bases de datos Sybase SQLServer, Oracle o Microsoft Visual FoxPro. Siempre que es posible, el controlador toma ventaja de las características back-end específicas, como los cursores o las consultas parametrizadas. En algunos casos, el controlador en sí cuenta con funciones específicas para suplir las características no soportadas por el back-end de la base de datos. Si el controlador no soporta la caracteristica requerida, éste regresa un error indicando que es incapaz de realizar la operacibn.
ODBC Desktop Database Drivers
6
o Windows NT 3.51 (o posterior). S610 se soportan aplicaciones de 32 bits en Windows 95; en Windows NT se soportan aplicaciones de 16 bits y de 32 bits.
Los
ODBC Desktop Database Drivers incluyen controladores de 32 bits para Microsoft Access, dBase, Microsoft Excel, Microsoft FoxPro, Paradox y Texto (Un controlador para Microsoft FoxPro 3.0 esta disponible por separado). No se tienen controladores de 16 bits. La Figura 1 muestra una lista de los controladores que estan disponibles para Windows. Cualquier otro controlador para cualquier otra base de datos que se desee agregar es necesario adquirirlo por separado con la compañía que fabric6 la base de datos.3.50.360 ... Microsoft Corp ... odbcit32.dll f) 3.50 .360... Microsoft Corp ... odbcjt32.dll b ) 3.50 .%O... Microsoft Corp ... odbcit32.d
csv) 3.50.360 ... Microsoft Corp ... odbcit32.dll 2.00.0301 Oracle Cor por... sqo32-73.d 2.65.0240 Microsoft Corp ... sqlsrv32.dll Microsoft ODBC Driver for Oracle 2.00.006 ... Microsoft Corp ... MSORCL1O.DLL
Figura
l. ODBC Desktop Database Drivers.1.3
Registro de una fuente de datos
El primer paso en el acceso a datos por ODBC es utilizar el manejador de fuentes de datos de ODBC para registrar la fuente de datos. Este paso es importante ya que así se almacena la inforrnacidn de la fuente de datos en el Registro de Windows y hace esta informaci6n disponible para las aplicaciones.
Para dar de alta una fuente de datos:
1) En el Panel de Control de Windows, dar doble-click en el icono 32bit ODBC.
7
En el cuadro de Configuraci6n, teclear el nombre de la fuente de datos o Data Source Name (DSN). Este puede ser cualquier cadena, como "VentasDB" o "Pubs". La cadena no tiene que corresponder con el nombre actual de la base de datos o tabla que se desea accesar.
Opcionalmente, teclear una descripción de la base de datos, como "Datos de Ventas para
1998. Se puede teclear cualquier texto.
Teclear el nombre de red del servidor en el cual reside la fuente de datos. No alladir el doble- backslash ("\\") para comenzar el nombre.
Teclear el nombre de la base de datos que se accesara. Por ejemplo, para especificar la base de datos de ejemplo de Microsoft SQL Server, teclear "Pubs".
La configuración para cada fuente de datos ODBC puede variar debido a que cada controlador requiere de un conjunto diferente de información. Si el dialogo de configuración de la fuente de datos que se esta agregando tiene valores no descritos en los pasos mostrados arriba, haga click en el botón de ayuda de la caja de dialogo para mas información.
Registrando una fuente de datos en el código
En algunos casos es deseable registrar la fuente de datos dentro del c6digo en lugar de dejarles a los usuarios el trabajo de configurarla con el manejador de fuentes de datos. Para hacer esto, se utiliza el m6todo RegisterDatabase del objeto DBEngine en Visual Basic 5.0.
El procedimiento mostrado en el Listado 1 registra una fuente de datos llamada "Cuentas" para una base de datos del mismo nombre en el servidor "ServCuentas".
Listado 1. Registro de una fuente de datos en Visual Basic.
Sub RegisterDB ( )
Dim str As String
' Construye la cadena de información.
str = "Description=SQL Server en Servidor ServCuentas" &
-
vbCr & "OemToAnsi=No" &
vbCr & "Network=(Default)" & -
vbCr & "Address=(Default) " & -
vbCr & "Server=ServCuentas" & -
vbCr & "Database=Cuentas"
' Registra la base de datos
DBEngine .RegisterDatabase "Cuentas", "SQL Server", True, str End Sub
2
La
API
de
ODBC
La lnterfaz de Programación de Aplicaciones (API) de la Conectividad de Bases de Datos Abiertas (ODBC) define un modelo de programación independiente de la base de datos que proporciona una sola interfaz que se puede usar para accesar cualquier base de datos o servidor de base de datos que tenga un controlador ODBC. AI usar la API de ODBC, se pueden desarrollar
aplicaciones que tengan el rendimiento y flexibilidad de los modelos de programación de código nativo. AI mismo tiempo, es posible mantener una aproximación general de programación universal que puede ser aplicado a diversos formatos de bases de datos.
Este capítulo da una breve descripción de la API de ODBC para tomar una decisión adecuada sobre el modelo de programación a utilizar en un aplicación ClientelServidor.
2.1 El
enfoque ClientelServidor
La API de ODBC es una interfaz de nivel de llamada (Call-Level Interface, CLI) a los controladores y librerías de ODBC. Estas librerías proporcionan conectividad para acceso a datos hacia el Microsoft SQL Server y hacia cualquier otra base de datos que proporcione un controlador ODBC. AI codificar con esta interfaz, se puede crear código independiente de la base de datos, lo cual significa que la API de ODBC proporciona un modelo de programación universal que
automaticamente se adapta a una gran variedad de bases de datos.
La
API
de ODBC a menudo es extendida con funciones especiales del controlador en sí-ademas de las que pertenecen al manejador del controlador ODBC. Por ejemplo, el controlador del SQL Server contiene varias funciones de su API las cuales no estan documentadas fuera del ambit0 del controlador. Ademas, esas funciones realizan tareas específicas del controlador, su uso podría no ser soportado en otros controladores. Si una aplicación esta pensada para ser utilizada dentro de10
una amplia variedad de sistemas back-end, se deben usar esas funciones con sumo cuidado o no utilizar todas las que hay.
La API de ODBC proporciona un extenso control sobre los errores y los mensajes y permite manejar la mayoria de las características de los servidores de back-end. La API de ODBC no implementa el ligado de controles con datos, pero
sí
cuenta con sus propios conjuntos de resultados que utilizan cursores tipo client-side o tipo server-side.El modelo de programacidn de la API de ODBC proporciona las siguientes características:
Un modelo de programaci6n universal que puede accesar a la mayoría de las arquitecturas de bases de datos.
Una interfaz nativa con Microsoft SQL Server.
Un manejo inteligente de parametros de Stored Procedures.
Soporte a cursores server-side en Microsoft SQL Server versidn 6.0.
Implernentacion de cursores keyset, dynamic, static y forward-only.
Manejo avanzado de conjuntos de resultados.
Acceso a virtualmente todas las características de SQL Server.
Manejo completo de errores post-llamada.
La Figura 2 ilustra como es que Visual Basic ejecuta c6digo de la API de ODBC, el cual directamente manipula los puntos de acceso de la librería del manejador de controladores de ODBC.
Estos
puntos de acceso se conectan al controlador que permite el acceso a un tipo específico de base de datos remota e implementa las operaciones de acceso a los datos. Usualmente no es necesario reescribir la aplicaci6n para acceder a un tipo diferente de base de datos. Todo lo que se necesita es cambiar el controlador de la base de datos remota.I
Código Visual BasicODBC Driver Manager
U
OracleServer Driver
Driver
Remote Database Engine
t
11
2.2
Objetos de Datos Remotos o llamadas a
funciones de la API de ODBC
La API de ODBC ha proporcionado una interfaz confiable a los desarrolladores de front-end de bases de datos que necesitan una plataforma rdpida y relativamente estable con la cual conectarse a los sistemas ClientelServidor. La API de ODBC está disefiada para correr en diversas
plataformas, incluyendo Windows de 16 bits, Windows
95
y Windows NT de 32 bits, y varios otros. Sin embargo, como la complejidad y la flexibilidad de dstas plataformas a evolucionado, la complejidad para usar el modelo de programaci6n de la API de ODBC en Visual Basic tambien se ha incrementado. Aunque es posible crear aplicaciones usando la API de ODBC desde Visual Basic, dsta no proporciona tantos beneficios como el uso de la interfaz Remote Data Object u otras interfaces de modelo-objeto-especialmente en plataformas de 32 bits. La conversión deaplicaciones ODBC API de 16 bits a 32 bits puede ser especialmente problemdtica cuando se tienen nuevos manejos de memoria y características Unicode, y otros requerimientos de c6digo de mayor complejidad.
En general, existen dos aproximaciones al uso de la API de ODBC:
Extensidn de RDO con la API de ODBC. Debido a que los Objetos de Datos Remotos (RDO) son, en su mayor parte, interfaces de objetos a la API de ODBC, tiene sentido utilizar las funciones de la API de ODBC en conjuncibn con una aplicacidn RDO u ODBCDirect. Usar
los
handles de ODBC proporcionados por las interfaces de nivel-objeto para llamar a las funciones de la API de ODBC puede ser una efectiva e inteligente forma de controlaraspectos de los objetos rdoEnvironment, rdoConnection, rdoQuery o rdoResultset.
Nota: Si se hace mal uso de ciertas funciones de la API de ODBC con handles dados por RDO, se corre el riesgo de fallas de protecci6n general inesperadas o perdida de datos.
Codificaci6n Directa a la API de ODBC. Es posible crear una aplicacidn usando la API de ODBC que no dependa de RDO u otra interfaz tipo objeto para obtener handles, abrir
conexiones, crear y manejar cursores, o realizar operaciones complejas de recuperacidn de datos, enlazado y de actualizaci6n. Todas dstas funciones pueden ser realizadas por la API de ODBC. Aunque se gana algún grado adicional de rapidez, flexibilidad y memoria con el uso directo de la API de ODBC, se tiene un impacto negativo en el tamano del programa y en su rendimiento, adem& de que es mucho rnds difícil de codificar y de mantener.
Nota: Algunos desarrolladores escogen la API de ODBC para accesar a las bases de datos de Microsoft Jet. Aunque es posible usar los controladores de ODBC proporcionados con algunas aplicaciones de Microsoft Office, dsta aproximaci6n requiere de la Jet database engine y siempre resulta en un pobre rendimiento al compararse con el uso de los Objetos de Acceso a Datos (DAO) para accesar este tipo de base de datos. Aun más, muchas de las características mas significativas de la Jet database no son aprovechadas por los limitados controladores Jet ODBC, de forma que se podrían experimentar algunas dificultades al realizar la mayoría de las operaciones bdsicas mediante dsta aproximaci6n.
12
2.3
Codificación directa a la API de ODBC
Se puede codificar directamente a la API de ODBC. Este modelo de programacidn utiliza el mismo administrador de controladores y controlador de ODBC específico que Jet usa. Sin embargo, es responsabilidad del programador manejar todos
los
aspectos de la conexidn, consultas, búffers, cursores y cualquier error que sea generado, dentro del cddigo de Visual Basic.La Figura 3 ilustra cdmo la declaracidn de sentencias de la API permite la comunicacidn con el administrador de controladores de ODBC para acceder a datos en una base de datos remota.
Visual Basic
+
*
*
+
MI Declare Statments
ODBC Driver
I
1
ODBC DriverNetwork Interface
I
+
Remote Database Engine
I I
Figura 3. El modelo de programación de la API de ODBC en Visual Basic.
El modelo de programacidn de la API de ODBC utiliza instrucciones Declare de Visual Basic, el administrador de controladores de ODBC y un controlador específico para la base de datos o servidor. La parte de declaraci6n de funciones de la API ODBC incorpora funciones de la interfaz de ODBC a Visual Basic y a
los
procedimientos que necesitan accesar la API. De esta forma las aplicaciones de Visual Basic pueden usar las funciones de la API como cualquier otra funcidn. La manera de hacer esto es la siguiente:Declare Function Beep Lib "kerne132" Alias "Beep" (ByVal dwFreq As Long, -
ByVal dwDuration As Long) As Long
Declare Function BringWindowToTop Lib "user32" Alias "BringWindowToTop"
-
(ByVal hwnd As Long) As Long13
Arquitectura del modelo de codificación directa
La arquitectura de Aplicación/Controlador en Windows 95 o posterior es:
Aplicación (32-bit)
ODBC Driver Manager (ODBC32.dll)
I
ODBC Desktop Database Driver
(ODBCJT32.dl1, MSJET35.dI1, 32-bit Driver ISAM)
I
base de datos
I
El uso de &tos controladores para aplicaciones de 16 bits en Windows 95 no esta permitido. La arquitectura de AplicaciÓnlControlador en Windows NT 3.51 o posterior es:
Aplicación (1 6-bit) Aplicación (32-bit)
I
I
ODBC Driver Manager (0DBC.dll)
I
I
16-Bit ODBC Generic Thunking DLL (ODBC16GT.dll)
I
I
32-Bit ODBC Generic Thunking DLL (ODBC32GT.dll)
I
I
ODBC Driver Manager (ODBC32.dll)
I
I
ODBC Desktop Database Driver
(ODBCJT32.dl1, MSJET35.dl1, 32-bit Driver ISAM)
I
base de datos
Nótese que en el caso de Windows NT se necesitan de dos librerías adicionales para las
14
2.4 La librería de enlace dinámico: ODBC32.DLL
Una librería de enlace dinamico (en inglks, dynamic link library, DLL) es un conjunto de programas o funciones previamente compiladas que son enlazadas en tiempo de ejecucibn por algún otro
programa que las necesite para ejecutarse. Estas librerías cuentan con una tabla de exportacidn, la cual indica las funciones que estan disponibles para uso público. Ademas, pueden contar o no con una tabla de importacibn, con la que hacen referencia a otras librerías que necesitan para su propia ejecucibn. La API de ODBC esta sustentada primordialmente por la librería de enlace
dinámico ODBC32.DLL, pues es en 6ste archivo donde residen-o se importan de otros drivers-la totalidad de las funciones de ODBC que vamos a necesitar para la conexidn y la manipulacibn de datos. Si bien se requieren de los ODBC Desktop Drivers o del Driver de la base de datos dada para realizar la conexibn, no es conveniente hacer llamadas a las funciones de &tos Drivers, ya que algunos incorporan sus propias funciones de ODBC y otras especiales. Si se planea hacer uso de las funciones de &tos Drivers conviene hacerlo con sumo cuidado por razones de portabilidad como se vio en la primera parte de 6ste capítulo.
Vamos a hacer un brevísimo analisis de la librería de ODBC, para ello nos valdremos del programa Quikview de Windows. Primero, busquemos el archivo ODBC32.DLL, ubicado en el directorio C:\Windows\Systern\ para Windows 95 o en C:\Winnt\System32\ para Windows NT. Una vez localizado el archivo hagamode un click con el botón derecho del Mouse y seleccionemos Vista @ida o Quikview según sea el caso. Veremos desplegarse una ventana con informacidn sobre el archivo seleccionado; pongamos particular atencidn en la parte designada como EXPORT TABLE, en 6sta sección se encuentra una lista de las funciones que han sido exportadas para su uso público, 6sta lista cuenta con tres columnas: Ordinal, Entry Point y Name. El primero es el número de la funcibn dentro del c6digo de la librería y corresponde a su posicidn ordinal, es decir, si es la primera, la segunda, la tercera, etc., los números de 6sta columna estan en hexadecimal. La
segunda columna corresponde a su mapeo en memoria una vez cargada la librería; por lo general una DLL contiene un valor hexadecimal que indica la direccibn de memoria preferida para ser
cargada, como se puede ver en el parámetro Base of Code, que tambi6n se muestra en el Quikview del archivo, pero, sin embargo, es posible que otra DLL se cargue primero en esa base de memoria y por lo tanto nuestra DLL no pueda cargarse en su direccibn base predeterminada, por Io que se requiere que la DLL sea Redireccionable (Relocatable), y en efecto lo es, lo cual significa que si no puede cargarse en su base predeterminada puede redireccionarse en otra base de memoria y todos los mapeos de memoria de las funciones cambiaran de acuerdo a la nueva base. La tercera columna corresponde al nombre de la funcibn que es como debe importarse o llamarse en el cbdigo que las utiliza. Algunas de las funciones m& importantes que pueden verse aquí son por ejemplo: SQLAIlocConnect, SQLAllocEnv, SQLAllocStmt, entre otras; &stas y algunas más, serán estudiadas a fondo en los capítulos siguientes.
3
Conexión
ODBC a bases de datos
Ya hemos visto cual es la naturaleza del ODBC, la que puede resumirse en un conjunto de funciones encapsuladas en una librería de enlace dinsmico llamada ODBC32.DLL. En éste
capítulo entraremos en detalle en el uso de las llamadas a la API relacionadas con la conexion a las bases de datos, el manejo de errores y la creación de conexiones múltiples.
3.1
Primero: Se requiere un handle de ambiente
Antes de que una aplicación pueda utilizar cualquiera de las funciones ODBC, éSta debe de inicializar la interfaz de ODBC y obtener un handle de ambiente con la funcibn SQLAllocEnv:
Dim rc a s integer, henv as Long rc = SQLAllocEnv(henv)
Si SQLAllocEnv regresa SQL-SUCCESS, el ODBC driver manager esta inicializado, y se ha reservado espacio en memoria para almacenar informacion acerca del ambiente. Si por el contrario la función falla, los DLLs de ODBC no se inicializaron correctamente. Solo se necesita ejecutar
SQLAllocEnv una vez ya que el handle de ambiente que se obtiene es capaz de soportar conexiones múltiples a fuentes de datos.
La función SQLAllocEnv
()
Propósito
SQLAllocEnv() coloca en memoria un handle de ambiente y los recursos asociados para éste. Una aplicacion debe de llamar primero a dsta funcidn antes que a SQLAllocConnect() o que cualquier
16
otra funci6n de ODBC CLI. El valor henv es pasado despues a todas las funciones que requieran un handle de ambiente como entrada.
Sintaxis
SQLRETURN SQLAllocEnv (SQLHENV *phenv);
Argumentos de la función
Tabla 1. Argumentos de SQLAllocEnv.
Tipo de dato Argumento Uso Descripci&n
SQLHENV Phenv Salida Apuntador al ambiente
~~~ ~
Comentarios
Sólo puede haber un ambiente activo a un mismo tiempo por aplicaci6n. Cualquier llamada posterior a SQLAllocEnv() regresa el handle de ambiente existente.
Se debe llamar a SQLFreeEnvO por cada SQLAllocEnv() que se haya ejecutado con Bxito para liberar los recursos asociados al handle.
Códigos de retorno
SQL-SUCCESS
SQL-ERROR
Si se regresa SQL-ERROR y phenv es igual a SQL-NULL-HENV, entonces no se puede llamar a SQLErrorO porque no hay un handle con el cual asociar informaci6n de diagn6stico adicional.
Si el c6digo de retorno es SQL-ERROR y el apuntador al handle de ambiente no es igual a SQL-NULL-HENV, entonces el handle es un handle restringido. Esto significa que el handle solamente puede ser usado en una llamada a SQLErrorO para obtener mas informaci6n del error, o por SQLFreeEnvO.
3.2
Segundo: Se requiere un handle de conexión
Antes de que una aplicacidn pueda conectarse a un controlador, Bsta debe obtener un handle para la conexión. La funci6n SQLAllocConnect se usa para este prop6sit0, como se muestra en el siguiente ejemplo:
Dim rc as Integer, hdbc as Long
rc = SQLAllocConnect (ByVal henv, hdbc)
17
La función SQLAllocConnect
()
Propósito
SQLAllocConnect() coloca en memoria un handle de conexibn y
los
recursos asociados para &te dentro del ambiente identificado por el handle de ambiente de entrada. SQLGetlnfo() con f/nfoType puesto a SQL-ACTIVE-CONNECTIONS, proporciona el número de conexiones que pueden ser almacenadas a un mismo tiempo. Se debe llamar a SQLAllocEnv() antes que a &a función.Sintaxis
SQLRETURN SQLAllocConnect (SQLHENV henv, SQLHDBC *phdbc);
Argumentos de la función
Tabla 2. Argumentos de SQLAllocConnect.
Tipo de dato Argumento uso Descripción
SQLHENV Henv Entrada Handle de ambiente
SQLHDBC * Phdbc Salida Apuntador a la conexi6n
Comentarios
El handle de conexibn de salida es usado por el ODBC CLI para referenciar a toda la informacibn relacionada con la conexibn, incluyendo informacibn del status general de la misma, estado de la transacción, e informacibn de los errores.
Si el apuntador al handle de conexibn (phdbc) apunta a un handle de conexibn valido obtenido por SQLA//ocConnect(), el valor original se sobreescribe en cada llamada a la funcibn.
Códigos de retorno
0 SQL-SUCCESS
SQL-ERROR
0 SQL-INVALID-HANDLE
Si se regresa SQL-ERROR, el argumento phdbc es puesto a SQL-NULL-HDBC. La aplicacibn debe entonces llamar a la funcibn SQL€rror() con el handle de ambiente (henv) y con
los
argumentos hdbc y hstmt puestos a SQL-NULL-HDBC y SQL-NULL-HSTMT respectivamente, para el chequeo de errores.3.3
Tercero: Se procede a la conexión
18
bases de datos requieren de conexiones adicionales para operaciones múltiples. Es mejor crear
varios handles de sentencia o instrucci6n en una sola conexibn que crear múltiples conexiones con una sola sentencia. Para determinar si el controlador de la base de datos soporta múltiples
sentencias activas en una sola conexi6n se utiliza la funci6n SQLGetlnfo.
Requisitos para la conexión
El c6digo debe proveer los siguientes argumentos para establecer una conexi6n:
0 Un handle de ambiente vdlido creado por SQLAllocEnv.
0 Un handle de conexi6n vdlido creado por SQLAllocConnect.
Un nombre de fuente de datos registrado que corresponde a la entrada DSN en el archivo
Un ID de usuario vdlido (opcional), el cual es el ID de acceso o nombre de la cuenta usado
Un password o contrasetia valida (opcional) que corresponde al ID del usuario.
Cualesquiera otros parametros opcionales que proporcionen informaci6n al controlador, con 0DBC.ini o en el registro del sistema.
para acceder a la fuente de datos.
la cual el controlador seleccionard una base de datos específica.
Creando el nombre de fuente de datos
(DSN) de ODBC
Cuando se abre una conexi6n a cualquier base de datos o servidor de base de datos remoto con la API de ODBC, se hace referencia a un nombre de fuente de datos o Data Source Name (DSN). Aunque es posible crear DSNs en el c6digo con la funci6n de ODBC ConfigDSN, la forma mas sencilla de crear o modificar un DSN es usando el programa Administrador del ODBC del Panel de Control.
La informaci6n del DSN se almacena en el archivo 0DBC.ini en los sistemas de 16 bits y en el registro del sistema en los sistemas de 32 bits. Si se tienen aplicaciones tanto de 16 bits como de 32 bits corriendo en un sistema operativo de 32 bits, tal como Windows NT o Windows 95, se deben establecer las entradas para el DSN para ambos casos, para el archivo 0DBC.ini y para el registro del sistema.
Tres maneras de culminar la conexión
Para establecer la conexibn, se pueden usar una de las tres funciones de la API de ODBC para pasar los parametros necesarios al manejador de controladores ODBC:
SQLConnect acepta un nombre de fuente de datos DSN, ID del usuario, y password como argumentos. SQLConnect cambia el estado de hDbc a conectado y regresa SQL-SUCCESS, SQL-SUCCESS-WITH-INFO o SQL-ERROR.
19
regresa SQL-ERROR si el usuario hace click en el botón Cancelar o si el manejador no se puede conectar por otras razones.
e SQLBrowseConnect soporta un metodo iterativo para determinar
los
controladores disponibles, fuentes de datos y otros pardmetros. La aplicación escoger& de las fuentes de datos disponibles.En éste trabajo
sólo
se describird a la función SQLConnect por ser la mas sencilla de todas y porque es una de las funciones del núcleo primario de funciones de la API de ODBC. Las otras dos funciones: SQLDriverConnect y SQLBrowseConnect, son extensiones de nivel 1 o nivel2
al WOpen and SQL Access Group Call Level lnterface y no siempre son soportadas por todoslos
drivers. Para determinar si un driver soporta una función específica, se utiliza la función SQLGetFunctions.La función SQLConnect
()
Propósito
SQLConnectO establece una conexión a una base de datos destino. La aplicación debe
proporcionar una base de datos destino, y opcionalmente un nombre de usuario y una cadena de autentificación o password correspondiente al nombre de usuario. Se debe llamar a
SQLAllocConnect() antes que a ésta función y a su vez esta función debe ser llamada antes que SQLAllocStmt().
Sintaxis
SQLRETURN SQLConnect (SQLHDBC hdbc,
SQLCHAR *szDSN,
SQLSMALLINT cbDSN,
SQLCHAR *szUID,
SQLSMALLINT cbUID,
SQLCHAR *szAuthStr,
SQLSMALLINT cbAuthStr) ;
Argumentos de la función
Tabla 3. Argumentos de SQLConnect.
Tipo del dato Argumento uso Descripci&n
SQLHDBC Hdbc Entrada Handle de conexión
SQLCHAR * SzDSN Entrada Fuente de datos: El nombre o alias de la base
SQLSMALLINT CbDSN Entrada Longitud del argumento szDSN SQLCHAR * SzU I D Entrada ldentificador del usuario
SQLSMALLINT CbUlD Entrada Longitud del argumento szUlD SQLCHAR SzAuthStr Entrada Cadena de autentificacion (password) SQLSMALLINT CbAuthStr Entrada Longitud del argumento szAuthStr
de datos.
Comentarios
20
Los argumentos de longitud en SQLConnect() (cbDSN, cbUID, cbAothSfr) pueden ser puestos como las longitudes actuales de los datos asociados. No se incluyen los caracteres de terminaci6n de nulo. Se puede usar SQL-NTS en los argumentos de longitud para indicar que el dato asociado esta terminado en nulo.
Los espacios a la izquierda o a la derecha en los valores de szDSN y SZUID son eliminados a menos que estos se encuentren enmarcados en comillas o comillas dobles.
Códigos de retorno
SQL-SUCCESS
SQL-SUCCESS-WITH-INFO
SQL-ERROR
SQL-INVALID-HANDLE
Ejemplo C
Listado 2. Conexión a una fuente de datos en C.
int connect(SQLHENV henv, SQLHDBC * hdbc) {
SQLRETURN rc;
SQLCHAR server[MAX-DSN-LENGTH t 11,
uid [MAX-UID-LENGTH
+
11 , pwd [MAX-PWD-LENGTH + 1 ] ;printf ("Servidor: \n") ;
gets ( (char * ) server) ;
printf ("Usuario: \n") ;
gets ( (char * ) uid) ;
printf ("Password: \n") ;
gets ( (char * ) pwd) ;
SQLAllocConnect(henv, hdbc); / * establece un handle de conexión * /
rc = SQLConnect (*hdbc, server, SQL-NTS, uid, SQL NTS, pwd, SQL-NTS); if (rc ! = SQL-SUCCESS)
printf("Error al intentar conectar a la base de datos\n"); return (SQL-ERROR) ;
printf ("Conexión exitosa\n") ;
return (SQL-SUCCESS);
-
1 else [
1
Ejemplo VB
Listado 3. Conexión a una fuente de datos en Visual Basic.
Dim rc as Integer Dim hdbc as Long Dim DSN as String Dim UID as String Dim PWD as String
'Inicializa el handle de conexión rc = SQLAllocConnect (henv, hdbc)
21
UID = "Tendo" PWD = "Kasumi"
rc = SQLConnect (hdbc, DSN, Len(DSN), UID, Len(UID), PWD, Len(PWD) )
if rc <> SQL-SUCCESS Then Else
End If
MsgBox "Error al intentar conectar a la base de datos''
MsgBox "Conexión exitosa"
3.4
Ultimo: Se liberan los recursos usados
Hasta ahora hemos visto los pasos necesarios para realizar una conexión a una base de datos, a saber son: obtener el handle de ambiente, obtener el handle de conexión y realizar la conexión en
sí.
Después de esto se pueden hacer todas las consultas que se necesiten a la base de datos y procesar la información obtenida. Pero después de esto que sigue? No es bueno dejar conexiones abiertas a diestra y siniestra, pues afecta al rendimiento del motor de base de datos, toda conexión abierta es un recurso en el servidor que implica memoria y tiempo de procesamiento, a mayor número de procesos, menor tiempo de atención para cada uno. Es por ello que se deben liberar los recursos asociados a una conexión una vez que se obtuvo y procesó la información deseada, cerrando las conexiones existentes. La forma de hacerlo en Visual Basic se ejemplifica en el fragmento de código que sigue:Dim rc as Integer
rc = SQLDisconnect(hdbc) 'Cierra la conexión a la BD
rc = SQLFreeConnect(hdbc) 'Libera el handle de conexión y l o s recursos rc = SQLFreeEnv (henv) 'Libera el handle de ambiente y los recursos
La función SQLDisconnect, cierra la conexión entre el servidor y la maquina cliente, pero es posible establecer conexión otra vez con la función SQLConnect usando el mismo handle de conexión, sin embargo, la función SQLfreeConnect libera al handle de conexión y ya no es posible usarlo para abrir otra conexión, a menos que sea establecido otra vez con SQLAllocConnect, lo mismo sucede con el handle de ambiente, con SQLfreeEnv se libera al handle y para poder obtener otro handle utilizable se debe llamar a SQLAllocEnv.
La función SQLDisconnect
()
Propósito
SQLDisconnect() cierra la conexión a una base de datos asociada con un handle de conexión. Después de llamar a 6sta función, se puede llamar a SQLConnect() para conectar a otra base de datos o a la misma, o llamar a SQLFreeConnectO para liberar los recursos del handle de conexión.
Sintaxis
22
Argumentos de la función
Tabla 4. Argumentos de SQLDisconnect.
Tino de dato Araumento uso DeSCriRCidn
SQLHDBC Hdbc Entrada Handle de conexión
Comentarios
Si una aplicación llama a SQLDisconnect antes de que se hayan liberado todos los handles de sentencia asociados con la conexidn, ODBC los libera despubs de que realiza la desconexión de la base de datos con bxito.
Si se regresa SQL-SUCCESS-WITH-INFO, esto implica que aunque la desconexibn de la base de datos fue exitosa, se tiene informacibn de implementacibn o de un error. Por ejemplo:
Se encontro un problema al hacer la limpieza despues de la desconexibn, o,
Si no existe una conexidn actual debido a un evento independiente de la aplicacibn (como una falla en la comunicacibn).
Despues de un exitoso SQLDisconnect(), la aplicacibn puede reusar hdbc para hacer otro llamado a SQLConnect().
Códigos de retorno
0 SQL-SUCCESS
SQL-SUCCESS-WITH-INFO SQL-ERROR
0 SQL-INVALID-HANDLE
La función SQLFreeConnect
()
Propósito
SQLFreeConnectO invalida y libera el handle de conexibn. Todos los recursos asociados al ODBC CLI con el handle de conexibn son liberados. Se debe llamar a SQLDisconnect() antes que a esta funcibn. Se puede llamar a SQLFreeEnvO para continuar con la terminacibn del programa, o a SQLAllocHandle(), para obtener un nuevo handle de conexibn.
Sintaxis
SQLRETURN SQLFreeConnect (SQLHDBC hdbc);
Argumentos de la función
Tabla 5. Argumentos de SQLFreeConnect.
Tipo de dato Argumento Uso Descripción
23
Comentarios
Si esta funci6n se llama cuando existe aún una conexi6n abierta, la funci6n regresa SQL-ERROR, y el handle de conexi6n permanece valido.
Códigos de retorno
SQL-SUCCESS SQL-ERROR
0 SQL-INVALID-HANDLE
La función SQLFreeEnv
()
Propósito
SQLFreeEnvO invalida y libera el handle de ambiente. Todos los recursos del ODBC CLI asociados con el handle de ambiente son liberados. Se debe llamar a SQLFreeConnectO antes que a M a funci6n. Esta funci6n es la última que debe llamar una aplicacidn antes de terminar.
Sintaxis
SQLRETURN S Q L F r e e E n v (SQLHENV h e n v ) ;
Argumentos de la función
Tabla 6. Argumentos de SQLFreeEnv.
Tipo de dato Argumento Uso Descripci6n
~~~
SQLHENV henv Entrada Handle de ambiente
Comentarios
Si ésta funci6n es llamada cuando aún existe un handle de conexi6n vAlido, la funci6n regresa SQL-ERROR, y el handle de ambiente permanece valido.
Códigos de retorno
SQL-SUCCESS SQL-ERROR
0 SQL-INVALID-HANDLE
3.5
Formato básico de una aplicación ODBC
24
un handle de ambiente hasta la liberacidn del mismo. Es imprescindible tener en cuenta que desconectar una fuente de datos no significa que el handle de conexi6n haya sido liberado, sino que ese mismo handle puede ser utilizado para establecer otra conexi6n con una fuente de datos distinta, mientras no se libere con la funcibn SQLFreeConnect.
Se tiene pues, un formato definido en la parte del acceso a datos de una aplicaci6n que usa ODBC, este consta de la obtenci6n de los handles necesarios, el procesamiento de sentencias de SQL y la liberaci6n de
los
recursos despues de hacerse las consultas. Como se muestra en la Figura 4, la parte de las consultas puede constar de varios ciclos de procesamiento de sentencias de SQL y de manejo de resultados, este ciclo puede durar tanto tiempo comolo
disponga un usuario o según sea la 16gica de la aplicaci6n.Se Obtienen los handles necesarios para la conexidn y se establece la misma
Se procesan las consultas mediante un handle de sentencia como se vera en el siguiente capítulo
Se desconecta de la fuente y se liberan los handles de conexidn
SQLAllocEnv
SQLAllocConnect
SQLConnect
SQLAllocStmt
Procesar sentencia SQL
Obtener resultados
SQLFreeStmt
SQLFreeEnv
Figura 4. Formato básico de una aplicación ODBC.
25
3.6
Conexiones múltiples y manejo de errores
Una aplicaci6n no necesariamente tiene que estar atada a una sola conexibn, una vez obtenido el handle de ambiente hem, se pueden tener todos los handles de conexi6n hdbc que se deseen y que los recursos de memoria permitan. Un handle de ambiente puede soportar varios handles de conexibn, así como un handle de conexi6n puede soportar varios handles de sentencia hsfmt. El Listado 4 muestra c6mo se realiza la conexion a dos fuentes de datos distintas utilizando el mismo handle de ambiente, cada conexi6n se hace dentro de una funcidn llamada conect, a la cual se le pasan como argumentos el handle de ambiente por valor, y por referencia una variable de tipo SQLHDBC la cual contendra el valor del handle de conexi6n obtenido para esa fuente de datos. La parte de creaci6n de sentencias para consultas se omite por simplicidad.
Listado 4. Ejemplo de conexidn a dos fuentes de datos distintas en C.
. . .
* * Conexión a dos fuentes de datos
* * Funciones usadas:
* * SQLAllocConnect SQLDisconnect
* * SQLAllocEnv SQLFreeConnect
* * SQLConnect SQLFreeEnv
. . . * *
* *
* *
* *
#include <stdio.h> #include <stdlib.h>
/ * Declaraciones de l o s tipos de datos y de las funciones ODBC * / #include "sqlcli. h"
int connect(SQLHENV henv, SQLHDBC * hdbc);
#define MAX-DSN-LENGTH 18 #define MAX-UID-LENGTH 10 #define MAX PWD LENGTH 10 #define MAXICONNECTIONS 5
int main() (
SQLHENV henv; / * Declara la variable de ambiente * /
SQLHDBC hdbc[MAX - CONNECTIONS]; / * Arreglo de variables de conexión * / / * Obtiene un handle de ambiente * /
SQLAllocEnv (&henv) ;
/ * Conecta con la primer fuente de datos * /
connect (henv, &hdbc [O] ) ;
/ * Conecta con la segunda fuente de datos * / connect (henv, &hdbc [ 11 ) ;
/ * * * * * * * * Inicia el procesamiento de resultados * * * * * * * * * / / * Obtener handle de sentencia, ejecutar sentencia, etc. * / / * En esta parte van las consultas y la obtención de * /
/ * resultados * /
/ * * * * * * * * Finaliza el procesamiento de resultados * * * * * * * /
26
SQLDisconnect (hdbc[Ol ) ; / *
SQLDisconnect (hdbcrl]) ; / *
SQLFreeConnect (hdbc [O] ) ; / *
SQLFreeConnect (hdbc[l] ) ; / *
SQLFreeEnv(henv); / *
Desconectando la primer fuente de datos * /
Desconectando la segunda fuente de datos * /
Liberamos el primer handle de conexión * /
Liberamos el segundo handle de conexión * /
Liberamos el handle de ambiente * /
. . . * * connect - Pide datos de conexión y realiza la conexi6n * *
. . .
int connect(SQLHENV henv, SQLHDBC * hdbc) {
SQLRETURN rc;
SQLCHAR server [MAX-DSN-LENGTH
+
11, uid[MAX-UID-LENGTH+
11, pwd[MAX-PWD-LENGTH+
11;SQLCHAR buffer[255] ;
SQLSMALLINT outlen;
printf ("Teclear nombre del servidor ->\n") ;
gets ( (char * ) server) ;
printf ("Teclear nombre del usuario -->\n") ;
gets ((char * ) uid);
printf("Tec1ear clave del usuario --->\n"); gets( (char * ) pwd) ;
SQLAllocConnect(henv, hdbc); / * obtiene un handle de conexión * / / * SQL-NTS indica que las cadenas pasadas finalizan con nulo * / rc = SQLConnect (*hdbc, server, SQL - NTS, uid, SQL-NTS, pwd, SQL-NTS) ;
if (rc ! = SQL SUCCESS) {
printf ("ErTor al intentar conectar a la base de datos\n") ;
return (SQL-ERROR) ;
printf("La conexión se realizó con éxito\n"); return (SQL-SUCCESS) ;
) else {
1 1
Observese del código anterior, que dado un handle de ambiente henv, se pueden hacer todas las conexiones que se deseen, el Único requisito es declarar una variable distinta para cada handle de conexi6n hdbc que se requiera; en el caso anterior se utiliz6 un arreglo de tipo SQLHDBC para almacenar los handles de conexibn obtenidos, lo cual es una soluci6n adecuada cuando no conocemos el número de conexiones que se van a establecer. Por supuesto que todas las
conexiones hechas deben cerrarse y tambien los handles de conexidn deben liberarse, por
lo
que se debe llamar a las funciones SQLDisconnect y SQLFreeConnect por cada conexi6n realizada, la ventaja de declarar un arreglo para los handles de conexibn es que la desconexi6n y liberacidn de recursos se puede hacer dentro de un ciclo For, que resulta muy sencillo de implementar.Manejo de errores
27
regresar. Debido a 6sta caracteristica de las funciones de ODBC en sus códigos de retorno, es posible hacer un manejo sencillo de errores al saber que códigos de retorno podemos esperar, para ello se pueden usar bloques If, Then o bloques Select, Case o Switch según sea el caso. Un ejemplo de éste manejo simple de errores lo podemos ver en el listado de código arriba presentado del cual extraemos la parte de interés para su estudio en el siguiente fragmento.
rc = SQLConnect(*hdbc, server, SQL-NTS, uid, SQL NTS, pwd, SQL-NTS); if (rc ! = SQL SUCCESS) {
printf ("Error al intentar conectar a la base de datos\n") ;
return (SQL-ERROR) ;
printf("La conexión se realizó con éxito\n"); return (SQL-SUCCESS);
-
1 else {
1
El bloque If, Then prueba para el Return Code (rc) SQL-SUCCESS, si el rc no es SQL-SUCCESS, se da por omisión que entonces es SQL-ERROR, pues se ha dado por entendido que no puede
ser SQL-INVALID-HANDLE que es el código de retorno restante para la función SQLConnect. Para hacer una prueba exhaustiva de los códigos de retorno usaríamos un bloque Switch, como se muestra en el siguiente fragmento de código C:
rc = SQLConnect (*hdbc, server, SQL - NTS, uid, SQL NTS, pwd, SQL-NTS) ;
swicth (rc) {
-
case SQL-ERROR:
printf("Error al intentar conectar a la base de datos\n"); break;
printf("La conexión se realizó con éxito\n"); break;
printf ("El handle proporcionado es inválido\n") ;
case SQL-SUCCESS:
case SQL-INVALID HANDLE:
1
De ésta forma se agotan todas las posibilidades para una función en particular, lo que permite hacer un manejo m& preciso de los errores. Con esto introducimos la función de manejo de
errores de la API de ODBC, la función SQLError. La función SQLError proporciona información sobre errores y advertencias (warnings), 6sta función debe llamarse en cualquier caso en que el código de retorno no sea SQL-SUCCESS, especialmente para SQL-ERROR y para SQL-SUCCESS-WITH-INFO.
La
función
SQLError
()
Propbito