Make your own free website on Tripod.com

 

Acceso a Bases de Datos remotas mediante objetos RDO

 

En la primera parte de esta capítulo hemos visto como acceder a bases de datos a través de ODBC usando el motor JET.  El acceso se realizaba mediante ODBCDirect, modo de operación del motor JET, y podíamos usar la misma sintaxis y objetos que habíamos visto con los objetos DAO. También vimos como crear un enlace ODBC, enlace que vamos a utilizar en este capítulo. Como ya se explicó en el capítulo anterior, damos por supuesto que el alumno conoce como crear ese enlace.

 

Los objetos RDO se crearon para cubrir el hueco que tenía VB para conectar con bases de datos distintas a las que trabaja el motor JET. (Access, dBase, FoxPro, etc.). Esta forma de trabajar nos permite enlazar con bases de datos tipo Oracle o SQLServer, pero también nos permite trabajar con Access, dBase o FoxPro,  que también tienen su propio driver ODBC.

 

Lo primero que nos encontramos al trabajar con RDO es que es más lento que DAO. Si creamos dos aplicaciones que trabajen sobre una base Access, una directamente a través de DAO y otra a través de RDO, observaremos que la primera accede a la BD con una rapidez mayor que la segunda. Normal, no es lo mismo abrir un fichero y leerlo (que es lo que hace DAO) que pasar unos parámetros a otro programa (Driver ODBC de Access) para que este abra el fichero, obtenga los datos y nos los pase. Lo mismo podemos decir cuando tenemos que contar registros, movernos de un registro a otro, editar o añadir nuevos registros. Esa falta de rapidez es el coste de la tecnología de bases abiertas.

 

Lo segundo que nos va a llamar la atención es el nombre de los objetos de acceso a datos. Una vez que nos habíamos familiarizado con palabras como Recordset,  DataBase o Dynaset, nos las cambian por rdoResultset,  rdoConnection o Keyset respectivamente.  Y lo peor no es solamente tener que aprender sus nombres, sino que en una aplicación hecha en DAO que sea necesaria cambiarla a RDO, nos vemos obligados a retocar la mayor parte de las líneas de código (Cosa que no ocurría con ODBCDirect)

 

Y lo tercero, RDO no tiene la posibilidad de crear bases de datos como hacíamos en DAO. Normal, ya que en este caso no trabajamos directamente sobre la BD sino sobre la conexión ODBC que Windows realizó a una base de datos. Podemos añadir mas desventajas de RDO: no puede contar los registros que tiene, tiene un comportamiento muy irregular con la propiedad AbsolutePosition, y varios detalles que procuraremos explicar en este capítulo para ahorrar al alumno el trabajo de tener que experimentarlos por sí mismo. (Aunque, consejo de viejo profesor, es la forma más segura de aprenderlos).

 

Tras estos inconvenientes parece lógico encontrar alguna contrapartida positiva. Por ejemplo poder conectar con cualquier tipo de base de datos, pudiendo incluso realizar la aplicación atacando una base Access, para luego trabajar con una base SQLServer u Oracle sin variar ni una línea de código. Esa debería ser la gran ventaja de RDO. Pero lamentablemente, y en contra de toda teoría de ODBC, no es cierto. Si preparamos una aplicación en RDO trabajando con una base Access y pretendemos cambiar la base por otra SQLServer, observaremos que lo que funciona perfectamente en la primera no funciona en la segunda. (Y esto no es teoría. Es simplemente experiencia del autor). ¡Y Access y SQLServer son del mismo fabricante!. La razón está en que los drivers de una base y otra no trabajan exactamente igual. Tampoco son iguales las protecciones y los permisos de acceso. Consejo de viejo profesor: Si va a trabajar con una determinada base de datos a través de RDO comience el proyecto usando esa base de datos. Y puestos a dar consejos, si piensa usar SQLServer u Oracle y si la aplicación va a escribir datos en la base no use RDO. Si solamente los va a leer no tendrá problemas. Y si tiene problemas nadie se los va a resolver, argumentando que deje RDO y use ADO. De hecho RDO ya se ha quedado obsoleto al nacer ADO. Pero eso será objeto de otro capítulo de esta Guía del Estudiante y hoy nos toca aprender RDO. Comencemos.

 

RDO y DAO.  Comparación de sus objetos. El control RemoteData

 

Al igual que DAO, RDO tiene objetos de acceso a datos, que deberemos declarar y crear. Mediante estos objetos podemos leer y escribir datos en una BD mediante código. También, al igual que en DAO existía el Control Data, con el que podíamos acceder a la base de datos sin escribir ni una línea de código, en RDO existe un control similar: el Control RemoteData. El funcionamiento es similar, pero las propiedades son distintas y tienen distintos nombres. Mediante el control RemoteData podemos enlazar una base de datos a los típicos controles enlazados a datos (Label, TextBox, DBGrid), pero en este caso se enlazan a través de una conexión ODBC, por lo que es fácil pensar que las propiedades de este control y los valores que deben tomar son distintas a los del control Data. Como es mucho más sencillo (sencillo no quiere decir mejor) usar el control RemoteData que trabajarse con código los objetos de acceso a datos, vamos a comenzar estudiando este control.

 

Pero antes vamos adelantar la equivalencia entre los objetos DAO y los objetos RDO. La lista siguiente está copiada literalmente de la información de Microsoft MSDN Library Visual Studio, información que merece la pena instalarla en su ordenador pese a lo que ocupa.

 

Objetos de datos remotos y los objetos de DAO/Jet equivalentes

Objeto de RDO

Objeto de DAO/Jet equivalente

rdoEngine

DBEngine

rdoError

Error

rdoEnvironment

Workspace

rdoConnection

Database

rdoTable

TableDef

No está implementado

Index

rdoResultset

Recordset

No implementado

Tipo Table

Tipo Keyset

Tipo Dynaset

Tipo static

Tipo Snapshot

Tipo dynamic

(ninguno)

Tipo forward-only

Tipo forward-only

No implementado (*)

User

RdoColumn

Field

rdoQuery

QueryDef

rdoParameter

Parameter

No implementado (**)

Relation

No implementado  (*)

Group

Control RemoteData

Control Data

 

(*) En RDO, los usuarios y grupos de usuarios son precisamente los que lleve implícitos la conexión ODBC.

(**) Al no trabajar directamente sobre la base de datos, no se pueden crear relaciones en ella.

 


El control RemoteData

 

Este control nos permite crear una aplicación de acceso a datos completa sin utilizar código. Eso sí, será necesario tener una conexión ODBC hecha, ya que el control RemoteData no abre un fichero de BD sino una conexión ya establecida.


No está normalmente en la caja de herramientas, por lo que habrá que añadirlo en Proyecto | Componentes introduciendo el Microsoft Remote Data Control 6.0  El control Remote Data tiene un aspecto similar al control Data, tanto en la caja de herramientas como en el formulario:

 

 


El control RemoteData toma por defecto el nombre MSRDCx.

 

Algunas Propiedades del Control RemoteData

 

DatasourceName

 

Devuelve o establece el nombre del origen de datos (DSN). El DSN No es más que el nombre de la conexión ODBC.

 

Esta propiedad se puede dejar en blanco si la propiedad Connect del control identifica un nombre de origen de datos (DSN) registrado en el Registro de Windows.

 

Sintaxis            NombredelControlRDO.DatasourceName = MiConexión

 

Puede cambiarse en tiempo de ejecución. En este caso, inmediatamente debe utilizar el método Refresh para abrir la nueva conexión con la base de datos.

 

Puede leer el valor de esta propiedad. Le devolverá precisamente el DNS que está utilizando. Esta propiedad sólo le devolverá un valor si ha introducido previamente algún valor en la propiedad DatasourceName. No le devolverá valor alguno si ha introducido la conexión a través de la propiedad Connect.


Propiedad Connect

Esta propiedad cumple la misma función que la anterior, pero por otro camino. Mediante la propiedad Connect le introducimos al control RemoteData la información necesaria para abrir la conexión, incluyendo en esta información, no solamente el nombre de la conexión, como hacíamos con la propiedad DatasourceName, sino ampliarla con otros datos de la conexión, tal como el nombre del usuario, su contraseña, nombre del controlador ODBC a usar, el nombre de la base de datos, el servidor donde se ubica esta base de datos, nombre de la estación de trabajo desde la que vamos a trabajar e incluso el nombre de la aplicación en la que vamos a usar los datos de esa base. Esta propiedad es mucho más completa que la anterior, pero un poco más complicada de usar.

 

Para introducir los datos de la propiedad Connect deberá usar una palabra para definir el dato, seguido del signo = y del dato a introducir. Como final del dato debe introducir necesariamente el signo punto y coma ;

 

DSN     Origen de datos ODBC registrado.                       DSN=MiConexiónODBC;

UID       Nombre de un usuario reconocido                        UID=Luis;

PWD    Contraseña asociada al usuario                           PWD=MiContraseña;

DRIVER            Descripción del controlador                     DRIVER=SQL Server;

DATABASE       Base de datos predeterminada

para usarla una vez conectado                 DATABASE=MiBase;

SERVER           Nombre del servidor donde se

aloja la base de datos                             SERVER=MiServidor;

WSID                Nombre de la estación de trabajo

                        (Nombre del PC que se va a

comunicar con el servidor                        WSID=NombredemiPC;

APP                 Nombre de la Aplicación que va a

Usar la Base de Datos                            APP=MiAplicación

 

 

NOTA - Si conoce SQLServer, DATABASE es el nombre de la base de datos que quiere utilizar una vez realizada la conexión. Para los que no conocen SQLServer, dentro de un fichero de esta base de datos pueden existir varias bases de datos. Y cada una de ellas puede tener varias tablas. Es decir, la configuración de esta BD no es tan simple como la de Access. Cada una de estas bases de datos tiene un propietario y varios usuarios. Cada usuario tiene habilitadas unas funciones (p.e. un usuario puede leer y escribir y otro solamente leer) Este parámetro le indica cual de esas bases de datos que contiene el fichero de SQLServer (para hablar con mas propiedad, el sistema de ficheros de SQLServer)

 


SQLServer mostrando su carpeta de Bases de Datos (BDGepa, master, model, …)

 


Observe que tras cada parámetro existe un separador ;   No es necesario introducir todos los datos. Dependerá del driver, de cómo haya creado la base de datos, los atributos que le dio a cada uno de los usuarios.  Y como no, dependerá del tipo de base de datos que esté usando (SQLServer, Oracle, etc.). Recuerde lo mencionado más atrás. No se fíe nunca de que su aplicación trabaja perfectamente sobre una base de datos. Lo más probable es que si cambia de BD ya no le trabajará tan perfectamente.

 

Veamos un ejemplo de cómo introducir esta propiedad:

 

Dim MiVariable As String

MiVariable = "DSN=MiConexionODBC;UID=Luis;PWD=MiContraseña;DATABASE=BaseGE;"

RemoteData1.Connect = MiVariable

 

El hecho de que podamos abrir una base de datos mediante DatasourceName o Connect tiene su explicación. Si tenemos creada una conexión ODBC con todos los datos necesarios para que pueda abrir una base de datos, es mucho más simple usar la propiedad DatasourceName y el Control RemoteData le abrirá perfectamente la BD. Pero cuando usamos una BD a través de Red de Area Local, lo normal es que esa base esté compartida por varios usuarios, que cada uno tendrá un nombre y un Password,  que puede estar habilitado para trabajar desde un puesto o desde varios puestos,  e incluso puede estar habilitado para trabajar sobre una BD utilizando una determinada aplicación, y no estarlo para utilizar esa misma BD con una aplicación distinta. Por eso este control nos brinda las dos posibilidades, una sencilla, DatasourceName, para trabajar con los datos ya introducidos en la conexión ODBC, y la otra, para variar los datos de esa conexión ODBC ya existente y lograr con ello todas las ventajas que nos ofrece ODBC respecto a restricciones de usuarios, contraseñas, etc. (la conexión ODBC en este caso es muy normal que tenga solamente el nombre, y que no apunte a ninguna base de datos concreta).  Puede incluso utilizar ambas propiedades. Es muy típico por ejemplo, que la conexión apunte a una determinada base de datos, (el nombre de la conexión se lo pasamos en la propiedad DatasourceName) y que en la propiedad Connect le pasamos el nombre del usuario y la contraseña.

 

Puede utilizar el control, RemoteData incluso sin tener una conexión preestablecida. Pero deberá establecer mediante el programa, utilizando los métodos OpenConnection o EstablishConnection. Se sale del contenido deseado para este curso comentar estos métodos, pero el alumno aventajado puede intentar obtener información en la escasa bibliografía existente. No le recomiendo que se complique la vida rizando el rizo, pudiendo establecer previamente la conexión ODBC.

 

 

Propiedad SQL

Mediante las dos propiedades estudiadas, DatasourceName y Connect hacemos que el control RemoteData sepa la conexión sobre la que va a trabajar - y por lo tanto la base de datos que utilizará. Ahora nos falta indicarle los datos que deseamos leer o escribir. Nos falta lo que sería en DAO, darle los datos para crear el Recordset (Por ejemplo el nombre de una tabla o una sentencia SQL, tal como hacíamos en la propiedad RecordSource del control Data).  Para el control RemoteData esta información se le introduce en la propiedad SQL

 

La propiedad SQL establece o devuelve una instrucción SQL válida para crear un conjunto de registros a partir del origen de datos establecido en las propiedades DatasourceName o Connect. Esta instrucción SQL debe comenzar necesariamente por SELECT,   En tiempo de ejecución, podemos asignar a esta propiedad el nombre de una Consulta ya almacenada en la BD, pero en este caso, debemos anteponer la palabra EXECUTE. También podemos introducir en esta propiedad un rdoQuery, un rdoResultset o un rdoTable. Eso lo veremos más adelante.

 

Para establecer esta propiedad en tiempo de diseño, basta con escribir la instrucción SQL en la ventana de propiedades. Una instrucción típica sería

 

                        SELECT * From Alumnos

                        SELECT * From Alumnos Where Apellido1= 'Suárez'

 

En tiempo de ejecución podemos introducir una de estas instrucciones en la propiedad SQL

 

            MSRDC1.SQL = "SELECT * From Alumnos Where Apellido1= 'Suárez'"

 

Si la BD tiene una consulta (la típica consulta de Access) llamada C_Suarez, donde hemos seleccionado todos los registros cuyo campo Apellido1 sea Suárez, podemos poner:

 

            MSRDC1.SQL = EXECUTE C_Suarez

 

(No intente hacer esto mismo con el nombre de una tabla. Solamente sirve para consultas)

 

Con los registros seleccionados por la propiedad SQL, formamos lo que en DAO era un recordset, pero en este caso adopta otro nombre: rdoResultset.  En RDO se ha buscado otra terminología, posiblemente para diferenciarlo claramente de DAO. Por ejemplo, en vez de registros es habitual hablar de Filas, y en vez de campos, hablamos de Columnas.

 

Si pudiésemos crear un rdoResultset mediante algún procedimiento, (y seguro que podremos hacerlo), podemos introducir directamente ese rdoResultset como rdoResultset del control RemoteData, al igual que lo hacíamos con el Recordset del Control Data en DAO:

 

            Set MSRDC1.Resultset = rdoResultsetYaCreado

 

Propiedad Connection

Veamos previamente que es un objeto rdoConnection.  Un Objeto rdoConnection es un objeto de acceso a datos remotos. Es el equivalente al objeto Database en DAO (Vea cuadro página 2) El control RemoteData tiene un objeto rdoConnection subyacente y podemos "verlo" mediante esta propiedad. El poner verlo entre comillas no significa otra cosa que, al igual que ocurría con el objeto Database, el objeto rdoConnection es un objeto de acceso a datos del que podemos ver sus propiedades y ejecutar sus métodos. Por ejemplo, si queremos ver la cadena de conexión completa podemos analizar la propiedad Connect del Objeto Connection:

 

            Label1 = MSRDC1.Connection.Connect

 

Si deseamos saber si el control RemoteData sigue conectado para realizar una determinada operación:

If MSRDC1.Connection.StillConnecting Then  ….

 

Podemos ejecutar uno de sus métodos. Por ejemplo, cerrar la conexión

 

            MSRDC1.Connection.Close

 

Propiedades EOFAction y BOFAction

 

Establecen el comportamiento del RemoteData cuando llega a la fila anterior a la primera o a la fila posterior a la última. (Y no es un juego de palabras) Puede establecerse en tiempo de diseño, mediante la caja de propiedades, o en tiempo de ejecución mediante la siguiente sintaxis:

 

MSRDC1.BOFAction = valor

MSRDC1.EOFAction = valor

Los valores (o constantes) que puede tomar son los siguientes:

 

Para la propiedad BOFAction

 

Valor     Constante         Efecto

 

0          rdMoveFirst      Se mueve a la primera fila

1          rdBOF              Se mantiene en la fila anterior a la primera. Se genera el evento

Validate y a continuación el evento Reposition, y se desactiva el botón de desplazar hacia abajo

 

Para la propiedad EOFAction

 

Valor     Constante         Efecto

0          rdMoveLast      Se mueve a la última fila

1          rdEOF              Se queda en la fila posterior a la última. Se genera el evento Validate

y a continuación el evento Reposition. Se desactiva el botón de

desplazar hacia arriba.

2          rdAddNew        Crea una nueva fila.

 

La propiedad EOFAction sólo tiene efecto cuando se manipula el cambio de filas mediante el ratón, sobre los botones del control RemoteData. No tiene efecto si se llega a la fila posterior a la última mediante código. (Por ejemplo, mediante la instrucción MSRDC1.resultset.MoveNext)

 

NO es recomendable establecer la propiedad BOFAction a 1 (rdBOF) ni la propiedad EOFAction a 1 (rdEOF), ya que puede entrar en una situación de la que es imposible salir. Si ve aparecer un aviso de error parecido a Estado del conjunto de datos no válido para Update le está indicando que se ha metido en un proceso del que no puede salir, debido a que se encuentra en el EOF ó BOF intentando introducir un nuevo dato, y no puede.

 

Propiedad CursorDriver

Devuelve o establece un valor que especifica el tipo de cursor que se va a crear. Veamos primero qué es un cursor. Según la definición de Microsoft:

 

Conjunto lógico de filas administrado por el origen de datos o por el administrador de controladores ODBC. Los cursores reciben dicho nombre porque indican la posición actual dentro del conjunto de resultados, igual que el cursor de la pantalla indica la posición actual. (#G!*¡&@%)

 

Vamos a no complicarnos la vida para intentar comprenderlo. El mecanismo de ODBC espera una base de datos albergada en un servidor, a la que le vamos a manipular sus registros desde un puesto conectado al servidor donde se encuentra la base de datos a través de una red de área local. Cuando creamos un recordset, el conjunto de registros que forma ese recordset deberá estar en la memoria RAM de algún equipo. ¿Del servidor? ¿Del cliente? En cualquiera de ellos que esté deberá estar en la memoria RAM, ocupando cierto espacio. A esa memoria ocupada por el recordset, y a la forma en la que están guardados los datos dentro de ella es a lo que llamamos Cursor. Este concepto de cursores es nuevo (No existía en DAO) debido a que RDO se utiliza fundamentalmente en sistemas basados en un servidor, donde se alberga la base de datos, y una serie de puestos de operación, unidos al servidor a través de una red.  El tráfico de datos a través de la red es algo que se debe optimizar. Y en algunos casos puede ser beneficioso llevarse todas las filas de un rdoResultset al puesto,  operar con ellas e introducirlas de nuevo, si es necesario, en la base de datos, una vez procesadas, o puede ser beneficioso mantener ese conjunto de filas en la memoria RAM del servidor para tener disponibles allí los datos y acceder a ellos de forma rápida a través de la red. En un caso lograremos o rapidez y en otro poco tráfico, pero en ambos casos gastaremos recursos. Podemos no crear un cursor, no usaremos memoria pero, o empleamos mas tiempo, o introducimos más tráfico en la red.

 

El crear un cursor de lado cliente o de lado servidor puede hacer que su código funciones o no funcione. Los cursores lado cliente suelen ser de lectura / escritura, que permiten avanzar hacia a delante y hacia atrás. Los cursores lado servidor suelen ser solamente de lectura y de avance solamente hacia delante. Hemos empleado una palabra no muy exacta: suelen ser.  Y es que eso dependerá de la base de datos (Oracle no se comporta como SQLServer, y ninguna de ellas se comporta como Access) y depende también del controlador ODBC que utilice (Hay controladores de varias marcas para la misma base de datos) Es muy frecuente realizar un código que funciona perfectamente con un controlador ODBC, y cuando se cambia de controlador – o de versión – ya no funciona. Le recomiendo mucho cuidado.

 

El control RemoteData permite elegir el crear un cursor en el servidor, en el puesto, o crearlo solamente si es necesario. Para ello usamos la propiedad CursorDriver.  Puede tomar los siguientes valores:

 

Constante

Valor

Descripción

rdUseIfNeeded

0

El controlador ODBC elegirá el tipo de cursores adecuado. Se usarán cursores del servidor si hay alguno disponible.

rdUseOdbc

1

RemoteData usará la biblioteca de cursores de ODBC .

rdUseServer

2

Se usarán cursores del lado del servidor.

rdUseClientBatch

3

RDO usará la biblioteca de cursores por lotes de tipo optimista.

Le recomiendo que repase el tema de cursores de la base de datos concreta que esté usando, y espero que la bibliografía que le brinda el fabricante sea suficiente. No suelen ser muy explícitos con los manuales aportados, o al menos tienen la habilidad de explicarlo de una forma tan sutil que es a veces inescrutable. Casi siempre esas dudas se resuelven en el curso que cada marca tienen para su base de datos, que es estrictamente de pago.

 

 

Métodos del control RemoteData

 

Método UpdateRow

Es equivalente al método UpdateRecord del Control Data. Guarda los valores actuales de los controles enlazados en la base de datos. El método UpdateRow tiene el mismo efecto que ejecutar el método Edit, modificar una columna y después ejecutar el método Update, excepto que no ocurre ningún evento.

 

Nota Cuando usa una biblioteca de cursores ClientBatch, todas las actualizaciones a las tablas base se retrasan hasta que use el método BatchUpdate. En este caso, el método UpdateRow actualiza el rdoResultset local, pero no actualiza las tablas base. Estos cambios pueden perderse si la aplicación termina antes de que se haya completado el método BatchUpdate.

 

Método BatchUpdate (Método del rdoResultset)

Este método no es del control RemoteData, sino de su rdoResultset asociado.

 

De igual forma que un control data tenía asociado un recordset, un RemoteData tiene asociado un Resultset. El Resultset es el objeto rdoResultset del control RemoteData (Colección de registros, o si lo prefiere, de filas ya que estamos en RDO), y que como cualquier objeto de acceso a datos, tiene sus métodos, y este es uno.

 

Realiza una actualización optimista por lotes.

 

Sintaxis           MSRDC1.Resultset.BatchUpdate (filaunica, forzar)

 

Donde MSRDC1 es el nombre del control RemoteData

Filaunica (Booleano) indica si es True, que solamente actualizará la fila actual, si es False, actualiza todo el lote. El lote es un conjunto de filas. Pueden ser las filas del cursor.

Forzar (Booleano)indica si está a True que sobreescribirá la fila actual, independientemente de si causa o no colisiones. Si está a False, no sobreescribirá si va a ocurrir una colisión.

 

Este método es un método del rdoResultset. Si tenemos un rdoResultset creado con código (Ahora veremos como se hace) la sintaxis sería

 

                        MirdoResultset. BatchUpdate (filaunica, forzar)

 

Con esta introducción ya podemos pensar que el alumno tiene cierta idea respecto a lo que es el control RemoteData. Vamos a comenzar a explicar lo que son los objetos de acceso remoto a datos (Objetos RDO) y podremos seguir viendo cosas acerca del control RemoteData como aplicación de estos nuevos objetos.


Objetos de datos remotos  (Objetos RDO)

 

Como ya conocemos los objetos de acceso a datos DAO, veremos los objetos RDO basándonos un poco en este conocimiento.

 

Los objetos de datos remotos nos permiten manipular componentes de un sistema de base de datos ODBC remoto. Lo de remoto no implica que la base de datos deba estar en un ordenador distinto al que tiene la aplicación. (Aunque esta sea la disposición más usual en aplicaciones que usan RDO). El significado de RDO es que se accede a la base de datos a través de una conexión ODBC.

 

RDO solamente funciona en plataformas de 32 bits. (Windows 95/98/2000 o Windows NT). Para usar objetos de datos remotos, debe establecer una referencia a Microsoft Remote Data Object 2.0 en Proyecto | Referencias.

 


Al igual que en DAO, los objetos RDO tienen una estructura jerárquica que se puede ver en la siguiente figura:

 


            Estructura jerárquica de los objetos RDO

 

Los objetos RDO siguen la misma regla para su creación que los objetos DAO: el objeto jerárquicamente superior crea al objeto inferior.

 

El Objeto rdoEngine

 

El objeto rdoEngine representa el origen de datos remoto. Es el equivalente al dbEngine de DAO, es decir, el motor de bases de datos. Es el objeto de nivel jerárquico superior, por lo tanto no se crea por otro objeto, sino que está creado simplemente al introducir la referencia.

 

La característica del rdoEngine es que trabaja siempre a través del Administrador de controladores. El objeto rdoEngine contiene al objeto rdoEnvironments (Colección de objetos rdoEnvironment) y el rdoErrors.

 

Los objetos rdoEnvironment de nueva creación se inicializan de acuerdo a los valores predeterminados establecidos en el objeto rdoEngine. Se crea de forma automática el objeto rdoEnvironments(0), al igual que lo hacía el dbEngine con el Workspaces(0) en DAO.

 

El objeto rdoErrors  contiene todos los mensajes de error enviados desde el origen de datos remoto. Cada vez que se recibe uno de estos mensajes, se produce el evento InfoMessage del rdoEngine

 

 

 

 

Propiedades del objeto rdoEngine

 

rdoDefaultLoginTimeout Determina el valor predeterminado la propiedad LoginTimeout de los objetos rdoEnvironment que se creen. Esta propiedad se utiliza en la administración del tiempo disponible para la conexión. Si la conexión no se ha realizado en el número de segundos indicado, dará error.

Sintaxis           rdoEngine.rdoDefaultLoginTimeout = NumeroDeSegundos

 

Si el valor NumeroDeSegundos es cero, esperará indefinidamente a que se realice la conexión.

 

rdoDefaultCursorDriver Determina el valor predeterminado de la propiedad CursorDriver de los objetos rdoEnvironment. Esta propiedad determina si el Administrador de controladores ODBC crea cursores por lotes del lado del cliente, locales, del servidor o si no crea cursores.

 

Sintaxis           rdoEngine.rdoDefaultCursorDriver = valor

 

Donde Valor es un valor o contante según puede verse en la siguiente tabla

RdUseIfNeeded            (Predeterminado) elige el estilo de cursores más apropiado para el

Controlador

RdUseODBC                 Utiliza la biblioteca de cursores ODBC.

RdUseServer                Utiliza cursores del servidor

RdUseClientBatch        Usa la biblioteca de cursores optimista por lotes

RdUseNone                  No crea un cursor desplazable. Básicamente es un conjunto de

resultados de sólo lectura de tipo forward-only

 

rdoDefaultUser y rdoDefaultPassword Determinan los valores predeterminados de las propiedades UserName y Password de los objetos rdoEnvironment cuando se abren conexiones sin suministrar valores para estos parámetros.

 

rdoVersion Examina la versión de RDO en uso.

rdoLocaleID Devuelve o establece un valor que indica la configuración regional de la biblioteca RDO, para mostrar los mensajes de error.

Sintaxis           rdoEngine.rdoLocaleID = valor

 

Por defecto, esta propiedad toma el valor 0, que pone la configuración establecida en Windows.

Si el archivo DLL del idioma especificado no está presente en el equipo del usuario, RDO se establece como rdLocaleEnglish, lo cual no requiere un archivo DLL independiente. Cuando esto ocurre, se coloca un mensaje informativo en la colección rdoErrors para indicar que RDO no pudo cargar el archivo DLL de recursos para la configuración regional especificada.

Cuando distribuya la aplicación, asegúrese de incluir el archivo DLL del lenguaje apropiado.

 

Métodos del rdoEngine

rdoCreateEnvironment   Este método es equivalente al CreateWorkspace de DAO. Crea un nuevo objeto rdoEnvironment. (Es decir, una sesión de trabajo)

Sintaxis                 Set MiSesion = rdoEngine.rdoCreateEnvironment(Nombre, Usuario, Contraseña)

 

Donde:

Nombre es la propiedad Name del nuevo objeto rdoEnvironment. (En el código, para nombrar a este rdoEnvironment debemos hacerlo con MiSesion). Debe suministrar un nombre, ya que si no lo hace, este rdoEnvironment creado no se suma a la colección rdoEnvironments.

Usuario es el nombre del usuario.

Contraseña es la contraseña usada en esa sesión. Puede tener hasta 14 caracteres.

 

Cuando se inicializa el rdoEngine se crea automáticamente una sesión de trabajo predeterminada, el rdoEnvironments(0), con el nombre de usuario que tenga el rdoEngine en su propiedad rdoDefaultUser y con contraseña igual a la propiedad rdoDefaultPassword. En una aplicación multiusuario es necesario crear un rdoEnvironment para cada uno de ellos, siempre que empleemos transacciones. En este método es necesario suministrar todos los parámetros (Nombre, Usuario y Contraseña)

rdoRegisterDataSource  Introduce la información de conexión en el Registro de Windows para un origen de datos ODBC (Crea una conexión ODBC igual que lo haríamos en Windows)

Sintaxis                        rdoEngine.rdoRegisterDataSource DSN, controlador, silencio, atributos

 

DSN es el nombre que queremos dar a la conexión ODBC

Controlador es el nombre del controlador ODBC. Debe ser uno de los instalados y hay que poner el nombre exacto por el que se le conoce en Windows, NO el nombre de la DLL. Por ejemplo, debe poner Microsoft Access Driver y no odbcjt32.dll

Silencio es un valor True / False y se refiere a si queremos que presente el cuadro de creación de un enlace ODBC (El mismo que aparece en Windows) Si ponemos False en esta propiedad, le introducimos los datos de la conexión a través de ese cuadro. Si le ponemos True, no mostrará el cuadro, y por lo tanto deberemos pasarle todos los parámetros correctamente. Si la información suministrada no es completa, mostrará el cuadro citado.

Atributos. Una expresión de cadena que es una lista de palabras clave que se van a agregar al archivo ODBC.INI. Las palabras claves están en una cadena delimitadas por retornos de carro. No es trivial esta cadena de caracteres y es propia de cada controlador. Por lo tanto, le recomiendo que si no conoce muy bien la cadena a introducir, ponga el parámetro Silencio a False y se olvide de este parámetro de atributos. Eso sí, deberá ser el usuario quien introduzca los datos a través del cuadro de creación del enlace ODBC.

 

Hasta aquí las propiedades y métodos del rdoEngine. Vamos a bajar un nivel jerárquico y ver el siguiente objeto RDO

 

 

El Objeto rdoEnvironment

 

Un objeto rdoEnvironment es una sesión de trabajo en RDO. Equivale al Workspace de DAO.  En un rdoEnvironment podemos tener varios objetos Connection (varias conexiones) de la misma forma que en un Workspace podíamos tener varias objetos Database.

 

La colección de todos los objetos rdoEnvironment es el objeto rdoEnvironments.  Visual Basic crea automáticamente un rdoEnvironment, de la misma forma que creaba un Workspace. El objeto rdoEnvironment creado es el rdoEnvironments(0) y el nombre de usuario será el que tenga el rdoEngine en su propiedad rdoDefaultUser y la contraseña igual a la propiedad rdoDefaultPassword

 

NOTA. Visual Basic crea automáticamente un Workspace o un rdoEnvironment si el proyecto contiene la referencia al motor de bases de datos correspondiente. Visual Basic no creará ninguno de ellos si no tiene la referencia a ningún motor de bases de datos.

 

Los objetos rdoEnvironment se anexan automáticamente a la colección rdoEnvironments a menos que no proporcione un nombre para el nuevo objeto cuando utilice el método rdoCreateEnvironment.

 

 

 

Propiedades del Objeto rdoEnvironment

 

Propiedad CursorDriver  Ya hemos visto esta propiedad para el control RemoteData. La aplicación al objeto rdoEnvironment es similar, por lo que solamente exponemos su sintaxis:

 

            MiSesión.CursorDriver = Valor   donde Valor toma uno de estos valores o constantes:

 

0          rdUseIfNeeded             El controlador ODBC elegirá el tipo de cursores adecuado. Se

usarán cursores del servidor si hay alguno disponible.

1          rdUseOdbc                   Usará la biblioteca de cursores de ODBC .

2          rdUseServer                 Se usarán cursores del lado del servidor.

3          rdUseClientBatch         RDO usará la biblioteca de cursores por lotes de tipo optimista.

 

 

Propiedad hEnv

Esta propiedad es el Handle de la conexión ODBC. Es similar a la propiedad hDC (para controles) o hWnd (para formularios) que ya hemos visto en capítulos anteriores. Esta propiedad es sólo de lectura y devuelve un Long. Este valor lo usan las APIs de Windows para trabajar. Alguna instrucción nos pedirá el hEnv como parámetro.

 

Propiedad LoginTimeout

Devuelve o establece el número de segundos que el Administrador de controladores ODBC espera antes de que se produzca un error de espera al abrir una conexión.

 

Sintaxis           NombreDelObjetordoEnvironment.LoginTimeout = NumeroDeSegundos

 

El valor predeterminado es el de la propiedad rdoDefaultLoginTimeout del objeto rdoEngine, y en su defecto, de 15 segundos. Si este valor es igual a 0 se espera indefinidamente y no se producirá ningún error.

 

Si establece un valor para esta misma propiedad en uno de sus objetos rdoConnection, este valor es prioritario al establecido en el objeto rdoEnvironment.

 

Métodos del objeto rdoEnvironment

 

Método OpenConnection

Abre una conexión con un origen de datos ODBC. En otras palabras, crea un objeto rdoConnection, objeto que deberá declarar antes de abrirlo:

 

Dim MiConexion as rdoConnection

Set MiConexión = MiSesion.OpenConnection(Nombre, LineaComandos, SóloLectura, Conectar, Opciones)

 

Nombre puede ser una conexión ya creada, en cuyo caso se abrirá esa conexión. Si este parámetro es una cadena vacía, deberá obtener los datos de la conexión, o bien del argumento Conectar, o mediante el cuadro de dialogo de abrir la conexión.

 

LineaComandos. Determina si muestra o no muestra el cuadro de diálogo de abrir la conexión ODBC. Puede tomar estos valores

rdDriverPrompt            (0)        Muestra el cuadro de diálogo

rdDriverNoPrompt        (1)        No muestra nunca el Cuadro de diálogo

rdDriverComplete        (2)        Muestra el cuadro de diálogo solamente si la información

facilitada no es suficiente para abrir la conexión.

RdDriverComplete       (3)        Igual que rdDriverComplete pero deshabilita las opciones
Required
                                  que ya estén bien pasadas en la información facilitada.

 

SóloLectura Determina si la conexión se abre como sólo lectura o para lectura / escritura. Si no se especifica nada, se abre para lectura / escritura.

 

Conectar Este es el argumento que lleva los datos completos de la conexión. Es similar a la propiedad Connect del control RemoteData, cuyo contenido repetimos aquí por comodidad.

 

Para introducir los datos de la propiedad Connect deberá usar una palabra para definir el dato, seguido del signo = y del dato a introducir. Como final del dato debe introducir necesariamente el signo punto y coma ;

 

 

DSN     Origen de datos ODBC registrado.                       DSN=MiConexiónODBC;

UID       Nombre de un usuario reconocido                        UID=Luis;

PWD    Contraseña asociada al usuario                           PWD=MiContraseña;

DRIVER            Descripción del controlador                     DRIVER=SQL Server;

DATABASE       Base de datos predeterminada

para usarla una vez conectado                 DATABASE=MiBase;

SERVER           Nombre del servidor donde se

aloja la base de datos                             SERVER=MiServidor;

WSID                Nombre de la estación de trabajo

                        (Nombre del PC que se va a

comunicar con el servidor                        WSID=NombredemiPC;

APP                 Nombre de la Aplicación que va a

Usar la Base de Datos                            APP=MiAplicación

 

Estos datos complementan la información de la conexión. Si ya habíamos establecido la conexión mediante el argumento Nombre, y en esa conexión ya estaban perfectamente definidos todos los parámetros de esa conexión, de este argumento Conectar solamente tomará el nombre de usuario y la contraseña.

 

Puede comprobar si se ha completado la conexión examinando la propiedad StillConnecting del objeto rdoConnection recién creado, que debe devolver False cuando se ha completado la operación de conexión.

 

If MiConexion.StillConnecting = false then ….

 

BeginTrans, CommitTrans, RollbackTrans  (Transacciones)

Son los métodos para realizar transacciones.

·         BeginTrans comienza una nueva transacción.

·         CommitTrans finaliza la transacción actual y guarda los cambios.

·         RollbackTrans finaliza la transacción actual y restaura las bases de datos del objeto rdoEnvironment al estado en que estaban cuando comenzó la transacción actual.

 

El funcionamiento en RDO es distinto al de DAO. Además, es distinto para cada base de datos. La forma de trabajar de SQLServer es distinta de cómo lo hace Oracle. Y muy distinta de cómo lo hace Access. Le recomiendo que estudie las transacciones en el manual de su gestor de base de datos.

Hay algunas bases de datos que no aceptan transacciones. Puede comprobarlo analizando la propiedad Transactions del objeto Connection.

 

 

Método Close

Cierra un el rdoEnvironment y todas las conexiones que tenía abiertas. Las modificaciones pendientes de los objetos RDO inferiores que estuviesen abiertos se deshacen.

 

Sintaxis                                    MiSesion.Close

 

No se puede cerrar el rdoEnvironments(0)  Si utiliza Close con el objeto ya cerrado, se producirá un error interceptable..

 

 

 

El objeto rdoConnection

Un objeto rdoConnection representa una conexión abierta con un origen de datos a través de ODBC.  Es el equivalente al Objeto DataBase de DAO

 

Un objeto rdoConnection (es decir, una conexión a una base de datos a trvés de ODBC) se crea o con un control RemoteData o mediante el método OpenConnection del objeto rdoEnvironment.

 

Puede también crear un nuevo objeto rdoConnection que no esté vinculado de forma inmediata con una conexión física específica a un origen de datos. Por ejemplo, el siguiente código crea un objeto rdoConnection independiente:

 

                Dim OtraConexion as New rdoConnection.

 

Posteriormente puede introducir las características que desee y establecer la conexión real con la base de datos. No es normal hacer esto, por lo que le remito en caso necesario, a la ayuda de VB de este objeto.

 

Propiedades del Objeto rdoConnection

 

Un objeto rdoConnection tiene Propiedades. Muchas de ellas ya se han visto, bien al estudiar el control RemoteData o los objetos RDO ya estudiados. Las propiedades que se han visto se describirán sólo de forma somera.

 

Propiedad Connect Devuelve o establece un valor que proporciona información sobre el origen de un objeto rdoConnection abierto. La propiedad Connect contiene la cadena de conexión ODBC. Esta propiedad puede leerse siempre, pero no puede modificarse una vez establecida la conexión.

 

Sintaxis           objeto.Connect = CadenaDeConexión

 

Las partes de CadenaDeConexión son:  (Puede no usar alguna de ellas)

 

DSN                 Nombre del origen de datos (Nombre de la conexión ODBC)

UID                   Nombre del usuario (Puede no tener nombre de Usuario)

PWD                Password. (Puede no tener Password)

DRIVER            Nombre del driver ODBC empleado

DATABASE       Nombre de la base de datos que se va a emplear

SERVER           Nombre del servidor remoto

WSIS                Nombre de la estación de trabajo dentro de la red

APP                 Nombre de la Aplicación

 

(El separador es el carácter punto y coma (;)

 

No es necesario aportar estos datos para crear la conexión, ya que son los que se han introducido en Windows al crear la conexión ODBC. Estos datos solamente son necesarios si la conexión ODBC se creó sin aportarle datos acerca de la base de datos.

Propiedad hDbc

Devuelve el controlador de conexión ODBC.

 

Sintaxis                       MiConexion.hDbc  

 

La propiedad hDbc devuelve un valor de tipo Long. Este valor lo utilizan las APIs de Windows. Y es similar a hDc o hWnd

 

Propiedad LastQueryResults

Devuelve un objeto rdoResultset, precisamente el que se ha generado la última consulta, si la ha habido. Esta propiedad podemos utilizarla para crear un nuevo Resultset, clónico del ultimo que se ha generado.

 

Sintaxis                      

Dim MiRs as rdoResultset

Set MiRs = MiConexion.LastQueryResults

 

Si no se había creado todavía ningún Resultset, devuelve Nothing.

 

Propiedad QueryTimeout

Devuelve o establece un valor que especifica el número de segundos que espera el Administrador de controladores ODBC antes de que se produzca un error de tiempo de espera al ejecutarse una consulta. El valor predeterminado es de 30 segundos.

 

Propiedad StillConnecting

Devuelve un valor que indica si la conexión se está estableciendo todavía.

 

Sintaxis           MiConexion.StillConnecting

Esta propiedad devuelve True si la conexión no ha terminado de establecerse, y False si ya está establecida. Es fundamental saber que la conexión ya está establecida antes de realizar ninguna operación con ella, por ejemplo, crear un Resultset

 

Propiedad StillExecuting

Devuelve un valor que indica si una consulta está aún ejecutándose. Esta propiedad se usa cuando creamos un rdoResultset o un rdoQuery, para conocer si ya se ha finalizado el proceso de selección de filas que esa operación implica. Esta propiedad puede aplicarse al rdoConnection, rdoQuery y rdoResultset.  Devuelve True cuando la consulta está ejecutándose todavía, False si ya se ha finalizado.

 

Sintaxis                       objeto.StillExecuting

 

Propiedad Transactions

Devuelve un valor que indica si se pueden realizar transacciones con un objeto rdoConnection ó rdoResultset. Esta propiedad le permite asegurarse de esta circunstancia antes de ejecutar la instrucción BeginTrans.

La propiedad Transactions llama a la función SQLGetInfo de ODBC para determinar si el controlador ODBC es capaz de permitir transacciones, no si el conjunto de resultados actual es actualizable.

 

 

Propiedad AsyncCheckInterval

Devuelve o establece un valor que especifica el número de milisegundos que espera RDO entre dos comprobaciones para ver si se ha completado una consulta asíncrona.

 

Sintaxis                        MiConexion.AsyncCheckInterval = valor

 

El valor por defecto es de 1 segundo (1000 mseg)

 

Comentarios  Al usar la opción rdAsyncEnable para ejecutar una consulta de forma asíncrona, RDO comprueba periódicamente el origen de datos para determinar si la consulta se ha completado. Puede modificar la duración del intervalo entre comprobaciones mediante la propiedad AsyncCheckInterval. RDO también comprueba el estado de las consultas asíncronas cuando se examina la propiedad StillExecuting.

 

Propiedad UpdateOperation

Esta propiedad afecta a la forma en la que se realiza la modificación de una fila en una actualización optimista por lotes. Si a esta propiedad se le pone el valor 0 (Predeterminado) la modificación de la fila se realiza mediante una instrucción Update. Si el valor es 1, la operación de modificación se realiza mediante dos instrucciones, primero una instrucción Delete (borra la fila)  y a continuación otra instrucción Insert (Crea la fila con los nuevos valores).

 

Sintaxis           objeto.UpdateOperation [= valor]

 

 

El Objeto rdoResultset

 

El Objeto rdoResultset es el conjunto de filas que devuelve la ejecución de una consulta. Es el equivalente al Recordset de DAO

 

El Objeto rdoResultset se crea mediante el método OpenResultset del rdoConnection.

 

Ejemplo:

‘Creamos el objeto rdoEnvironment utilizando el objeto creado automáticamente por VB

Set GepaWs = rdoEnvironments(0)

‘El objeto rdoEnvironment crea el objeto rdoConnection

Set GepaConex = GepaWs.OpenConnection(“Gepa”, rdDriverNoPrompt, False)

‘(Gepa es el nombre de la conexión ODBC creada en el ordenador)

‘El objeto rdoConnection crea el objeto rdoResultset

 

Set GepaRs = GepaConex.OpenResultset("Select Ex_expedite, Ex_numproye, " & _

"Ex_presenta, Ex_plan, Ex_tipoexpe, Ex_tipoprop, Ex_tipotram, Ex_redaproy, Ex_situxpe, " & _

"Ex_Numero_Ini, Ex_subsiste " & _

"From Expedientes Order By Ex_Numero_Ini", rdOpenDynamic, rdConcurRowVer)

 

Puede ver que el proceso de creación de un rdoResultset en RDO no difiere demasiado de la creación de un recordset en DAO.

 

Veamos cada una de las partes del Método OpenResultset

 

Set MirdoResultset = MiConexión.OpenResultset(nombre [,tipo [,tipoBloq [,opciones]]])

 

Donde

MirdoResultset = variable tipo rdoResultset que debe estar declarada.

MiConexión =    Objeto Connection con el que se crea el rdoRsultset

Nombre =          Nombre de una tabla o consulta de la base de datos, o una sentencia                                            SQL que pueda devolver filas.

Tipo =               Tipo de cursor que se va a crear

TipoBloq =         Tipo de bloqueo de la base de datos. Por defecto, lo crea solo lectura.      

Opciones =       Opciones que puede tener el rdoResultset

           

El argumento Tipo puede tener una de estos valores:

 

Constante                    Valor    Descripción

rdOpenForwardOnly    0          (Predeterminado) Abre un rdoResultset tipo forward-only.

rdOpenKeyset              1          Abre un rdoResultset tipo Keyset

rdOpenDynamic           2          Abre un rdoResultset tipo Dinamico

rdOpenStatic               3          Abre un rdoResultset tipo estático

 

El tipo forwar-only es un rdoResultset en el que las filas solamente se pueden explorar en sentido ascendente. No se puede retroceder .

El tipo Keyset es un rdoResultset que se puede actualizar, insertar nuevas filas, y se puede recorrer en ambos sentidos sin limitación. Los miembros de este rdoResultset son fijos.

El tipo Dinámico es un rdoResultset que se puede actualizar, insertar nuevas filas, y se puede recorrer en ambos sentidos sin limitación. Los miembros de este rdoResultset no son fijos.Es similar al Dynaset de DAO.

El tipo estático presenta los valores existentes en la BD en el momento de su creación y no detecta las posibles variaciones de los datos en la misma. Es similar al Snapshot de DAO

 

Para el parámetro Tipo de Bloqueo acepta los siguientes datos:

 

Constante                    Valor    Descripción

rdConcurReadOnly      1          (Predeterminado) Sólo lectura.

RdConcurLock             2          Concurrencia pesimista.

rdConcurRowVer         3          Concurrencia optimista basada en el Id. de fila. rdConcurValues 4          Concurrencia optimista basada en valores de filas. rdConcurBatch       5          Concurrencia optimista usando actualizaciones de modo por                                                             lotes. Valores Status devueltos por cada fila actualizada con                                                         éxito.

 

El parámetro opciones acepta estos valores:  (Se pueden sumar ambas)

 

Constante                    Valor    Descripción

rdAsyncEnable             32         Ejecuta la operación de forma asíncrona.

rdExecDirect                64         (Predeterminado) Evita la creación de procedimientos                                                                   almacenados para ejecutar la consulta.

 

El objeto rdoResultset tiene algunas particularidades que no tienen los recordsets de DAO, por ejemplo, poder obtener resultados múltiples, es decir, se pueden introducir varias sentencias SELECT y cada una de ellas crea un conjunto de registros. Esto no significa que haya mas de un rdoResultset, sino que existe un único rdoResultset con resultados múltiples. Se puede ir accediendo a cada uno de los conjuntos de registros mediante el método MoreResults.

 

Propiedades del Objeto rdoResultset

 

El rdoResultset no tiene exactamente las mismas propiedades que el Recordset.  Y además no siempre funcionan tal como lo hacían en el recordset. En RDO van a depender del tipo de cursor y del tipo de bloqueo. Veamos las propiedades del rdoResultset

 

AbsolutePosition.  Igual que en RDO, pero no siempre funciona, ya que depende del tipo de cursor.

 

ActiveConnection   Devuelve una referencia a la conexión con la que está asociado el rdoResultset

 

BatchCollisionCount   Devuelve un valor que especifica el número de filas que no finalizaron la última actualización por lotes. Devuelve un Long.  En caso de que esta propiedad sea mayor de 0 significa que la actualización por lotes no se ha completado con éxito. En este caso habrá que ejecutar el método BatchUpdate para completar la actualización.

BatchCollisionRows

Devuelve una matriz de marcadores que indica las filas que han provocado colisiones en la última operación de actualización por lotes. Devuelve un Variant con una matriz de las filas que han provocado una colisión la última vez que se invocó el método BatchUpdate. El número de elementos de esta matriz es el que indica la propiedad BatchCollisionCount

 

BatchSize (Propiedad)

Devuelve o establece un valor que especifica el número de instrucciones enviadas al servidor en cada lote. De forma predeterminada se envían 15 instrucciones al servidor en cada lote. Esta propiedad puede modificarse en cualquier momento. Si un DBMS no admite lotes de instrucciones, puede establecer esta propiedad a 1, con lo que cada instrucción se enviará por separado.

 

BOF, EOF    Son idénticas a las mismas propiedades del Recordset de DAO

 

Bookmark   Funciona igual que en el Recordset de DAO. Pero en RDO es posible que esa propiedad no se pueda usar. Depende del tipo de cursor. Para asegurarse de que el objeto rdoResultset admite marcadores, examine el valor de su propiedad Bookmarkable antes de usar su propiedad Bookmark. Si Bookmarkable es False, el objeto rdoResultset no admite marcadores y el uso de Bookmark producirá un error

La propiedad Bookmark no se aplica a los objetos rdoResultset de tipo forward-only.

 

En DAO la variable donde se guarda el Bookmark debía se un String. En RDO es un variant. Desconozco la razón, pero usando una variable String para almacenar el Bookmark falla.

 

Bookmarkable   Devuelve un valor que indica si un objeto rdoResultset admite marcadores, es decir, si acepta la propiedad Bookmark.

 

EditMode      Devuelve un valor que indica el estado de edición de la fila actual. Devuelve un integer o una constante de acuerdo con la tabla siguiente:

 

Constante                    Valor    Descripción

 

RdEditNone                  0          No se está efectuando ninguna operación de modificación.

RdEditInProgress         1          Se ha invocado el método Edit y la fila está en buffer de copia.

RdEditInProgress           2          Se ha invocado el método AddNew y la fila actual del búfer de                                                            copia es una fila nueva que no se ha guardado en la B. D.

 

LastModified    Devuelve un marcador que indica la última fila modificada o agregada más recientemente. Este marcador es el Bookmark de esa fila.  Devuelve un Variant.

LockEdits   Devuelve un valor de tipo Booleano que indica el tipo de bloqueo en vigor. Si devuelve True utiliza bloqueo pesimista. Si devuelve False utiliza bloqueo optimista.

Si LockEdits es True y otro usuario ya tiene la página bloqueada, se producirá un error al intentar usar el método OpenResultset. En general, los demás usuarios pueden leer datos de las páginas bloqueadas.

Si LockEdits es False (valor predeterminado) y utiliza después Update mientras la página está bloqueada por otro usuario, se producirá un error.

 

El bloqueo se realiza sobre una página de datos. La página suele se de 2 K (Ese es el tamaño que utiliza Microsoft SQL Server)

 

LockType Devuelve o establece un valor entero de tipo Long que indica el tipo de tratamiento de concurrencia. Los valores admitidos son:

Constante

Valor

Descripción

rdConcurReadOnly

1

(Predeterminado) El cursor es de sólo lectura. No se admiten actualizaciones.

rdConcurLock

2

Concurrencia pesimista.

rdConcurRowVer

3

Concurrencia optimista basada en el identificador de fila.

rdConcurValues

4

Concurrencia optimista basada en los valores de las filas.

rdConcurBatch

5

Concurrencia optimista con actualizaciones por lotes. Se obtienen valores de estado para cada fila actualizada correctamente.

Lea la ayuda de VB para obtener mayor información de cada uno de los tipos.

Restartable  Devuelve un valor que indica si un objeto rdoResultset admite el método Requery, que vuelve a ejecutar la consulta en la que está basado el objeto rdoResultset. Debe usarse antes de utilizar el método Requery para evitar que se produzca un error.

PercentPosition

Devuelve o establece un valor que indica o modifica la ubicación aproximada de la fila actual en el objeto rdoResultset, basándose en el porcentaje con respecto al total de filas de dicho objeto. El valor devuelto es un Single entre 0,0 y 100,0

 

Puede usar la propiedad PercentPosition con una barra de desplazamiento de un control Form o TextBox para indicar la ubicación de la fila actual en un objeto rdoResultset.  Esta propiedad solamente se aplica a los rdoResultset tipo Keyset y Dynamic.

 

RowCount  Devuelve el número de filas a las que se ha tenido acceso en un objeto rdoResultset.  Es un Long.

Esta propiedad no indica el número de filas del Resultset, sino el número de filas a las que se ha accedido. No es por lo tanto, el equivalente a la propiedad RecordCount del Recordset DAO.

Si esta propiedad no está disponible en el controlador, devuelve -1

 

Status   Devuelve o establece el estado de la fila o columna actual. El valor de esta propiedad indica si la fila o la columna estarán implicadas en la próxima actualización optimista por lotes y de qué modo lo estarán.

 

Los valores admitidos para la propiedad Status son:

 

 

 

 

Constante

Valor

Valor de la propiedad Prepared

rdRowUnmodified

0

(Predeterminado) La fila o la columna no se han modificado o se han actualizado correctamente.

rdRowModified

1

La fila o la columna se han modificado y aún no se han actualizado en la base de datos.

rdRowNew

2

La fila o la columna se han insertado con el método AddNew, pero aún no se han insertado en la base de datos.

rdRowDeleted

3

La fila o la columna se han eliminado, pero aún no se han eliminado de la base de datos.

rdRowDBDeleted

4

La fila o la columna se han eliminado localmente y también de la base de datos.

 

StillExecuting Devuelve un valor de tipo Booleano que indica si una consulta está aún ejecutándose.

Esta propiedad es muy útil (muy necesaria) para saber si la consulta ya está disponible, antes de presentar los datos de esa consulta. La propiedad debe ser False para poder presentarlos. Es típico crear un bucle parecido a este:

 

Do While GepaRs.StillExecuting = True

DoEvents

Loop

 

Transactions  Devuelve un valor Booleano que indica si un rdoResultset permite transacciones.

 

Type    Devuelve un Long el tipo de rdoResultset. (0 = rdOpenForwardOnly, 1 = rdOpenKeyset, 2 = rdOpenDynamic, 3 = rdOpenStatic)

 

Updatable Devuelve un valor Booleano que indica si se pueden efectuar cambios en el rdoresultset

 

Métodos del Objeto rdoResultset

 

El rdoResultset tiene algunos métodos comunes con el Recordset de DAO, sin embargo no se puede esperar que funcionen siempre de la misma forma. En DAO era Visual Basic quien abría la base de datos, y una base muy concreta, Access, dBase, etc., bases que controla directamente Visual Basic a través de la dll correspondiente a la versión de la BD que vamos a abrir. Esto no es exactamente igual en RDO. Aquí quien abre el fichero que contienen la base de datos no es Visual Basic, sino el driver de ODBC. Y no solamente eso, dependiendo de la base de datos, unas permiten hacer unas operaciones y otras no. Lo mismo podemos decir del tipo de rdoResultset, del cursor y de si es lado cliente o lado servidor. Por lo tanto no se asuste si pretende ejecutar un método y no funciona. Probablemente es que Visual Basic ha puesto por defecto unas características a los objetos que no son las adecuadas.  Y si no fuese posible, en última instancia nos queda realizar directamente la operación que pretendíamos realizar con el método, es decir, mediante las operaciones que nos permite el propio driver de ODBC. Eso sí, en este caso estamos en sus manos. Lo veremos más adelante.

 

 

 

 

 

 

Método AddNew

Crea una nueva fila para un objeto rdoResultset actualizable.

 

Sintaxis                        MirdoResultset..AddNew

 

Funciona igual que el mismo método de DAO, se ejecuta el método AddNew, se introducen los datos en los campos y se termina la operación con el método Update, que es cuando los datos entran en la base de datos. Si se está usando cursores de tipo Client Batch los datos se escribitrán en la BD cuando se ejecute el método BatchUpdate.

Hay que tener cuidado, pues el método AddNew no devuelve ningún error si se intenta añadir una nueva fila a un rdoResultset no actualizable. Ese error va a salir cuando ejecutemos el método Update.  Para evitar este error hay que comprobar la propiedad Updatable del rdoResultset.

Debe tener cuidado también con asegurarse que tras el método AddNew ejecuta el método Update antes de cambiar de fila, ya que de no hacerlo se pierden los cambios realizados y VB no avisa de ese error.

Si desea interrumpir la entrada de datos, una vez ejecutado el método AddNew puede anularse usando el método CancelUpdate

 

                        MirdoResultset. CancelUpdate

 

La fila recién añadida no pasa a ser la fila actual. Sigue siendo fila actual la que era anteriormente. Para que sea la nueva la fila actual basta con poner el siguiente código:

 

MirdoResultset.BookMark = MirdoResultset.LastModified

 

Pero eso sí, el rdoResultset debe aceptar marcadores. Para comprobarlo, se usa la propiedad Bookmarkable.

 

 

Método BatchUpdate

Realiza una actualización optimista por lotes. Veamos que significa esto.

Este método solamente se puede aplicar a un rdoResultset del tipo Client Batch (Cuando se crea el rdoResultset usando como tercer parámetro rdUseClientBatch) El tipo de rdoResultset puede ser Keyset o Dynamic. En estas condiciones, cuando usamos el método Update para guardar los datos, solamente se guardan en el rdoResultset local, pero no se meten en la base de datos.  Cuando se ejecuta este método, se envían a la base de datos todos los cambios pendientes.

 

Sintaxis            MirdoResultset.BatchUpdate (filaÚnica, forzar)

 

El parámetro filaÚnica es un Booleano que si es True, hace que la actualización sea solamente de la fila actual. Si es False, se actualizan todas las filas pendientes.

forzar es tambiénun Booleano que si es True fuerza a escribir los valores, aunque puedan causar colisiones.

 

Si usa el método CancelBatch, se descartan los cambios guardados en el objeto rdoResultset local.

 

 

Método Close

Cierra un rdoResultset abierto.  Es igual al método Close del Recordset de DAO

 

Sintaxis                        MirdoResultset.Close

 

Método Delete

Elimina la fila actual de un objeto rdoResultset actualizable.

 

Sintaxis           MirdoResultset.Delete

 

Es posible deshacer la eliminación de una fila si emplea transacciones y el método RollbackTrans, suponiendo que usa BeginTrans antes que el método Delete.

 

Se producirá un error al utilizar Delete si:

 

No hay ninguna fila actual.

La conexión o el rdoResultset es de sólo lectura.
Ninguna columna de la fila es actualizable.
La fila ya se ha eliminado.
Otro usuario ha bloqueado la que contiene la fila.
El usuario no tiene permiso para realizar la operación.

 

Método Edit

Inicia la operación de cambiar los valores de los datos de la fila actual o en un objeto rdoResultset actualizable.  Funciona de la misma forma que el método del mismo nombre del Recordset de DAO. Al igual que en el método AddNew, es necesario terminar la operación con el método Update.

 

Sintaxis                        MirdoResultset.Edit

 

Si cambia la fila actual antes de ejecutar el método Update, se perderán los cambios. Si desea anular el cambio que está realizando, basta con ejecutar el método CancelUpdate.

 

Cuando la propiedad LockEdits del objeto rdoResultset es True (bloqueo pesimista), todas las filas del conjunto de filas del objeto rdoResultset se bloquean en cuanto se ejecuta Edit, y se mantienen bloqueadas hasta que se ejecuta Update.

 

Método GetRows

Recupera múltiples filas de un rdoResultset y las introduce en una matriz.

 

Sintaxis                        matriz = MirdoResultset.GetRows (filas)

 

Donde filas es el número de filas que se quieren recuperar. Es un Long

matriz es un Variant

 

El primer subíndice de la matriz identificará la columna y el segundo identifica el número de fila, de esta forma:

                                matriz(intColumn)(intRow)

Método MoreResults

 

Este método se utiliza cuando se ha creado un rdoResultset de resultados múltiples, es decir, se han empleado varias sentencias SELECT para crearlo. Cada sentencia formará dentro del rdoResultset un juego de filas. Cuando se utiliza el método MoreResults se borran las filas del conjunto de resultados actual y se colocan en su lugar las filas correspondientes al siguiente.  El método devuelve un Booleano que es True si ha encontrado un nuevo conjunto de resultados, o False si no lo ha encontrado. No todas las bibliotecas de cursores son compatibles con consultas de conjuntos de resultados múltiples. Por ejemplo, la biblioteca de cursores del servidor no es compatible con este tipo de consultas si no desactiva el procesamiento del cursor en un cursor de sólo lectura sólo hacia adelante con la propiedad RowsetSize a 1.

 

Método Move

Cambia la posición de la fila actual en un objeto rdoResultset. Funciona igual que el mismo método del Recordset de DAO

 

Sintaxis                        MirdoResultset.Move filas[, inicio]

 

 

Métodos MoveFirst, MoveLast, MoveNext y MovePrevious

Funciona de la misma forma que los métodos del mismo nombre en el Recordset de DAO.

 

Método Requery

Actualiza los datos de un objeto rdoResultset volviendo a ejecutar la consulta en la que está basado el objeto.

 

Sintaxis                        MirdoResultset.Requery [opciones]

 

El valor admitidi para Opciones es rdAsyncEnable (32) que ejecuta la operación de forma asíncrona

 

Método Update

Termina una operación de modificación de datos o de añadir una nueva fila. Ya se ha comentado su funcionamiento con los métodos AddNew y Update.

 

 

No vamos a profundizar más en los objetos RDO. Su comportamiento es muy parecido a DAO, exceptuando los nombres de los objetos, y las particularidades del ODBC en cuanto a la situación de los cursores.

ODBC es una tecnología ya obsoleta (En el año  2002) y no debe emplearse para nuevos proyectos. Lógicamente un curso de Visual Basic debe incluir RDO, pero siempre para aplicarlo al mantenimiento de aplicaciones ya existentes. No se debe emplear para nuevos proyectos, ya que si se quiere emplear ODBC es mucho más práctico y sencillo emplear DAO en su versión de ODBCDirect. Tendrá código compatible con DAO, y más rapidez que con RDO. Además RDO es una tecnología considerada obsoleta por Microsoft, con lo que ello conlleva.

Microsoft dice, y este autor recomienda:   USE ADO EN TODOS SUS NUEVOS PROYECTOS

 

Pero si usa Access con la base de datos instalada en el mismo ordenador que el programa, use directamente DAO. Si usa Access olvídese de nuevas tecnologías. Con Access DAO significa: Rapidez, sencillez, eficacia, control sobre el programa, independencia de drivers.

Home | VB |