Professional Documents
Culture Documents
14
ACTIVE X DATA OBJECT (ADO)
O
L Bases de datos
E Relacionales
D
A
B
D
Aplicación que accede a los datos
O
O
D
B Texto
C
R
D Bases de datos
O relacionales
O D
B
C
D
A
O
Modelo DAO/RDO
Las características específicas que proporciona ADO para entornos de Cliente/Servidor (C/S)
son:
• Creación de los objetos de forma independiente. No se necesita navegar por ninguna
jerarquía de objetos para poder crearlos. La mayoría de los objetos se pueden
instanciar de forma independiente. De esta forma crearemos solo los objetos que
necesitemos.
• ADO nos permite utilizar los procedimientos almacenados en el sistema gestor de la
base de datos (si este soporta esta funcionalidad), pudiendo recoger los resultados
devueltos por dichos procedimientos como parámetros de salida. Esta característica
permite mejorar el rendimiento y la rapidez de las aplicaciones.
• Diferentes tipos de cursores.
• Soporte para limitar el número máximo de registros devueltos de una sola vez en un
recordset. Esta característica mejora el rendimiento tanto de la aplicación como de la
red.
• Soporte para recibir varios recordset como resultados devueltos de un procedimiento
almacenado.
Hay que tener en cuenta que todas estas características están limitadas por el servidor de los
datos. Es decir, si el servidor de datos no soporta procedimientos almacenados, no podremos
utilizar con él las características de ADO que se refieren a dichos tipos de procedimientos.
Connection*
Errors Error*
Command*
Parameters Parameter*
Recordset
*
Fields Field*
* Todos los objetos marcados con un asterisco contienen la colección Properties con un
subconjunto de objetos Property.
Properties
Property
Como puede verse en la figura, existen tres objetos principales dentro de ADO: El objeto
Connection, el objeto Command y el objeto recordset. Luego veremos algunas de las
características principales de cada uno de estos objetos.
Antes de proseguir con estos objetos vamos a explicar donde y porqué se deben utilizar
objetos ADO en vez de objetos DAO u objetos RDO
Hasta ahora habíamos utilizado bases de datos Access, y también otras bases de datos
sencillas como dBase. Acceder a Access es extremadamente fácil. Y ello es debido a que
Access es una base de datos sin grandes aspiraciones en cuanto a seguridad. Es una gran
base de datos, y tiene sus dispositivos de seguridad en cuanto a permisos de acceso (Vea El
dbEngine. Visión desde DAO y la propiedad SystemDB en el Capítulo 12) sin embargo estas
posibilidades se usan en muy pocas ocasiones, y estos mecanismos de seguridad de Access
Cuando queremos empezar a tener una seguridad en los accesos, disponer de privilegios
distintos para cada usuario, trabajar en una red de área local con muchos usuarios, hay que
recurrir a bases de datos tipo Oracle o SQLServer. Ya empezamos a tener problemas: Visual
Basic no puede acceder directamente a abrir estas bases de datos. Podemos acceder a través
de ODBC, pero como ya se dijo en el, capítulo correspondiente, ODBC se ha quedado
obsoleto. Y Microsoft ha sacado para ello ADO. Y ADO permite abrir la base de datos usando
para ello un dispositivo intermedio que es el proveedor OLE DB. Este no es más que una DLL.
Mejor dicho, un juego de DLLs que puede ver en la carpeta:
Estas DLLs permiten conectar con las bases de datos más conocidas (Oracle, SQLServer,
Access y las demás BD controladas por el motor Jet). ADO funciona de forma diferente a
ODBC. Con ODBC se preparan conexiones permanentes en el ordenador, y cualquier
programa puede acceder a la BD a través de esas conexiones. Con ADO no hay que preparar
previamente ninguna conexión. Es el propio programa el que llama al proveedor de datos OLE
DB y le pasa como parámetros los datos necesarios para que este realice la conexión y abra la
BD. Si hubiese dos programas ejecutándose simultáneamente y accediendo a la misma base
de datos a través de ADO, cada programa prepara una conexión a esa BD. En ODBC
podríamos ver las conexiones existentes en el PC a través del Panel de Control | Fuentes de
Datos ODBC. En ADO no existe esa posibilidad ya que, como se ha dicho, es el propio
programa quien crea esa conexión al ajecutarse.
Una particularidad de ADO frente a lo ya visto con DAO o RDO es que ADO se salta la
jerarquía a la hora de crear nuevos objetos. En DAO, el objeto DAO superior creaba al objeto
DAO inferior (Recuerde aquello del juego de niños). En ADO podemos crear cada objeto sin
que exista el objeto inmediatamente superior. Por ejemplo podemos crear un recordset sin
que exista el objeto Connection. Claro que en este caso, a la hora de crear el objeto
recordset deberemos indicarle, mediante los parámetros que debemos aportar en la sintaxis
de creación del recordset, todos aquellos datos que le aportaríamos a la creación del objeto
Connection. Como ve no tiene ventajas. Solamente que nos desentendemos un poco de
abrir y cerrar el objeto Connection.
EL OBJETO CONNECTION
El objeto Connection representa una sesión con el origen de los datos. Dependiendo de la
funcionalidad del proveedor de los datos podremos utilizar determinadas propiedades,
métodos y colecciones de este objeto. La función de este objeto es recoger toda la información
del proveedor de los datos que se va a utilizar para crear un objeto recordset.
Para crear un objeto Connection, previamente debemos declararlo como variable objeto
Connection:
El sitio donde se debe declarar depende como siempre, del ámbito que deseamos que tenga
ese objeto.
Nota: En el caso de que ejecutemos la aplicación y nos salga un error diciendo que el tipo no
está definido por el usuario, es que no hemos añadido la referencia de “Microsoft Actives
Data Objects Library x.x”
La conexión ¿está creada?. Sí, pero de momento es completamente inútil ya que no sabe ni
siquiera que base de datos debe abrir, ni con que usuario, ni las condiciones en las que debe
abrir esa base (Solo lectura, etc.) Esta información se la pasamos mediante la propiedad
ConnectionString (Cadena de conexión)
La propiedad ConnectionString
Es la propiedad más importante del objeto Connection. Se basa en encadenar una serie de
argumentos en una cadena de caracteres. Los diferentes argumentos son (dependiendo del
proveedor OLE DB y de la configuración de la red, se necesitarán todos o parte de ellos)
Como ejemplo para la conexión a una base de datos Oracle, con el usuario que esa BD tiene
por defecto (scott) y el Password de este usuario (tiger) tendremos que especificar en el
ConnectionString la siguiente cadena de caracteres.
donde el valor de Source es la cadena de conexión de Oracle que previamente tiene que estar
configurada con el SQL*Net o Net8 de Oracle.
Si lo que queremos es crear una conexión con una base de datos Access 2000
‘Provider=Microsoft.Jet.OLEDB.4.0;Data
Source=C:\GuiadelEstudiante\PruebaADO.mdb;’
‘Provider=Microsoft.Jet.OLEDB.3.5;Data Source=C:\GuiadelEstudiante\db1.mdb;’
Como puede comprobar, resulta una tanto complicado construir la cadena de conexión y
mientras que seamos novatos en ADO podemos tener problemas para crear esta cadena.
¿Pero es que no existe una manera más fácil de construir esta cadena? Efectivamente. Hay
un pequeño truco mediante el cual no solo podemos crearla con un asistente, sino que además
probaremos si la conexión es satisfactoria o no.
1) Primero tenemos que incluir el componente “Microsoft ADO data control 6.0 (OLEDB)”.
Podemos hacerlo pulsando Ctrl.-T o en el menú Proyecto Componentes.
2) Metemos en nuestro formulario el control y pulsamos F4 para ver sus propiedades.
3) Hacemos Click en la propiedad
ConnectionString y nos
aparecerá el botón de puntos
suspensivos. Hacemos Click en
el botón.
5) Al pulsar el botón generar, nos aparece otra ventana en la que tenemos cuatro
pestañas aunque únicamente necesitaremos dos de ellas para crear una cadena de
Prueba satisfactoria
Para seguir un poco el ejemplo que acompaña a este capítulo, vamos a ver el código utilizado
para crear la conexión. En el ejemplo usamos una base de datos Access (No es la mejor para
demostrar como funciona ADO, pero es la que los alumnos van a tener con mayor facilidad.
Una base Oracle o SQL no se instala fácilmente en un ordenador personal)
Ahora nuestro programa ya está en contacto con la base de datos. Lo que falta ya lo puede
suponer: crear un recordset.
Aquí vamos a ver la primera diferencia con DAO. El recordset no lo crea el objeto Connection.
Se crea él a sí mismo. Para que pueda existir un objeto Recordset primero hay que declararlo:
Set MiRecordset = New ADODB.Recordset (Ya está creado. Pero no está abierto, ahora
hay que abrirlo)
Ya tenemos abierto el recordset. En este caso el recordset está formado por todos los registros
con todos sus campos de la tabla Alumnos, que está en la base de datos definida en la
conexión MiConexion, es del tipo Dynamic y el bloqueo de escritura es optimista.
Podríamos elegir ciertos registros, y solamente unos campos. Utilizaríamos una sentencia SQL
Hagamos una pequeña pausa. Observe que hay diferencias de trabajar con ADO o hacerlo con
DAO.
Con DAO.
Declarar MiRecordset
Dim MiRecordset As ADODB.Recordset
Crear el Recordset
Set MiRecordset = New ADODB.Recordset
Abrir el Recordset
MiRecordset.Open "Alumnos", "Provider=Microsoft.Jet.OLEDB.4.0;Data
Source=C:\GuiaDelEstudiante\ADO\PruebaADO.mdb;Persist Security Info=False",
adOpenDynamic, adLockOptimistic
Observe siempre que tanto en las declaraciones del objeto Connection y del objeto Recordset,
como en su creación, debemos anteponer siempre la palabra ADODB
MiRecordset.Close
MiSesion.Close (Recuerde que debe cerrar antes el recordset que la conexión)
Cuando resumíamos en la página anterior el código a usar si usábamos DAO o ADO, parecía
(aunque no fuese cierto) que podíamos asimilar estos objetos
DAO ADO
Recordset Recordset
DataBase Connection
WorkSpace ¿
Efectivamente el Workspace no tiene algo que pudiésemos decir “equivalente” en ADO. Esto
es debido a que ADO ya considera que el acceso desde los usuarios lo gestiona directamente
la base de datos. Recuerde que el Workspace en DAO era una “sesión de trabajo” de la base
de datos, donde podíamos asociar un Workspace a cada usuario. ADO ya le pasa a la BD el
nombre del usuario y su Password para que la propia base de datos quien autorice a ese
usuario.
Los recordsets abiertos mediante una consulta SQL (aquellos en los que seleccionamos parte
de los registros mediante Select … Where van a crearse solo de lectura.
Independientemente de los parámetros que le pasemos a la hora de crearlos. La descripción
del error va a ser algo así como que el cursor es solamente de lectura. También observará con
frecuencia, cuando intente ir a un registro anterior al actual, MiRecordset.MoveFirst, p.e.) que
le enviará un error diciendo que el cursor es solamente de avance hacia a delante. Estos
efectos los observará también cuando use la instrucción SQL Order By. No hay que arrojar la
toalla solamente por esto. Cuando eso ocurra, lo que hay que hacer es volver a crear el
recordset de forma que acepte escritura y movimiento hacia atrás. Eso generalmente se logra
abriendo el recordset con todos los registros de la tabla, e incluyendo en él todos los campos.
En vez de :
MiRecordset.Open "Select Alumno_Nombre, Alumno_Ape1, Alumno_Ape2 From Alumnos " _
& “Where Alumno_Nombre = ‘Luis’”, MiConexion, adOpenDynamic, adLockOptimistic
Ahora ya nos permitirá usar el método AddNew. Basta con añadir las líneas de código
adecuado para introducir los valores en cada campo:
Mirecordset.AddNew
MiRecordset!Alumno_ID = Valor numérico
MiRecordset!Alumno_Nombre = Valor string
Etc.
….
MiRecordset.Update
No renuncie nunca a intentar hacer esto. No siempre funciona. Pero esto es mucho más
sencillo que introducir los datos “a capón” utilizando la instrucción SQL Insert que ya veremos
más adelante. SQLServer es bastante más dócil que Oracle para usar el método AddNew.
A este respecto, hay que citar la propiedad CursorLocation que veremos más adelante. Si
creamos un cursor lado cliente, seguramente nos permitirá utilizar más opciones (entre ellas
AddNew) que si lo establecemos de lado servidor. Tenga en cuenta que si usa un cursor lado
cliente, el recordset no se actualiza cuando otro usuario realiza modificaciones en la base.
En ADO no hace falta usar Edit para modificar los datos del registro actual. Edit no existe en
ADO. Para modificar un dato basta con poner el mismo código que utilizábamos en DAO, pero
sin comenzar por la línea Mirecordset.Edit. Colocándonos en el registro a modificar
pondremos:
MiRecordset!Alumno_Nombre = “Pedro”
MiRecordset!Alumno_Ape1 = “Perez”
MiRecordset.Update
De cualquier forma, esto tampoco tiene porque funcionar en todas las bases de datos. En ese
caso tendremos que recurrir, al igual que para un registro nuevo, a las instrucciones SQL, que
en este caso será Update. Pero ya lo veremos más adelante. Hasta ahora solamente he
querido usar el código más simple para que pueda empezar con ADO, y sobre todo, para que
vea que esta es una técnica completamente accesible, aunque, dadas las grandes
prestaciones que tiene, un poco más adelante se va a complicar algo.
Ya ha visto que podemos trabajar perfectamente con recordsets, tal como lo hemos hecho con
el DAO de toda la vida. Pero ya lo comentábamos al principio, parece que hay que adornar lo
obvio para que no lo parezca tanto. Y ahí viene el Objeto Command, que como habrá podido
ver en la figura de la Jerarquía de los objetos ADO, es un objeto que aún no sabemos lo que
hace.
MiRecordset.AddNew
ConexBDPrensa.Execute StrIntroducir
Con la instrucción anterior, lo que hacíamos era añadir un registro. Si lo que queremos hacer
es crear un recordset, la instrucción SQL comenzaría por “Select * From ….” Y el método
EXECUTE devolvería un Recordset
Podemos crear un recordset (MiRecordset, previamente declarado como tal) con esta
instrucción
Ahora, tras la explicación informal de cómo se crea una conexión y un recordset en ADO, y
que es un Command, vamos a entrar a conocer sus propiedades y métodos. Al final, y con un
buen ejemplo realizado de varias formas, entenderá perfectamente la forma de trabajar con
ADO.
visto como crear un objeto Connection, por lo que vamos a pasar directamente a ver sus
objetos, colecciones, propiedades y métodos.
Como puede verse en la figura, el Objeto Connection tienen los objetos Command y
Recordset, y la colección Errors.
Propiedades del Objeto Connection (Lea esto de las propiedades sin complicarse
demasiado la vida. Las realmente importantes verá que están advertidas debidamente)
Las propiedades del objeto Connection dependen de cada proveedor. No todos se comportan
de igual forma, por lo que cada propiedad debe condicionarse a si el proveedor es capaz de
ofrecerla.
Propiedad Attributes
adXactCommitRetaining
adXactAbortRetaining
La cadena de conexión tiene varios argumentos, todos ellos separados por un punto y coma (;)
de la forma
argumento1 = valor; argumento2 = valor; argumento3 = valor etc.
ADO procesa solamente cuatro argumentos: Provider, File Name, Remote Provider y Remote
Server. Los demás argumentos los pasa al proveedor para que el los procese (Usuario,
Password, etc)
Los cursores son, por decirlo de alguna manera, los mecanismos de la base de datos donde se
crean los recordsets. Se estará dando cuenta que las bases de datos que tienen cursores son
ya bases de datos con mecanismos propios para la creación de recordsets. (SQL Server u
Oracle, p.e.) Estas bases de datos trabajan como aplicaciones cliente – servidor. Tienen en el
servidor, aparte de los datos, la mayoría de sus recursos. En el cliente tienen prácticamente los
recursos de conectividad, y poco más. Esta conectividad permite enviar desde el cliente una
petición a la base de datos alojada en el servidor. Esa petición será el resultado por ejemplo,
de una sentencia SQL. Al recibirla el servidor, gestionará la obtención de los resultados y una
vez que los haya conseguido viene su primera duda: ¿Dónde los almaceno? Puede
almacenarlos en el servidor, y cada vez que necesitemos un nuevo registro, por ejemplo al
ejecutar la sentencia MiRecordset.MoveNext, el cliente se lo indica al servidor y este le envía
el nuevo registro. También puede almacenar los datos obtenidos en el cliente, y de esta forma
el cliente puede moverse con entera libertad a lo largo de los registros del recordset. Puede
hasta contarlos y saber en que posición está. La diferencia entre uno y otro sistema es que en
el primer caso el tráfico por la red es mínimo (solamente se envía la información estrictamente
necesaria) y en el segundo caso, se envía mucha información de un golpe, la correspondiente
a todos los registros del recordset, independientemente de si se va a usar en el servidor o no.
Considerando el tráfico generado, parece que es mejor crear los cursores en el lado servidor.
Pero esto trae también sus dificultades. Nos priva de muchas propiedades del recordset. Una
propiedad muy usada, AbsolutePosition, no la tienen los cursores de lado servidor,
circunstancia que no nos debe sorprender, ya que al no estar todos los registros en el cliente,
éste, aunque disponga de todos los datos guardados en todos los campos de un determinado
registro, no puede saber que posición ocupa ese registro dentro de la totalidad de registros del
recordset. Por lo tanto, usar cursores de lado cliente o lado servidor será siempre una decisión
a tomar dependiendo de la velocidad de la red, de la memoria disponible en el cliente, de la
complejidad del programa, etc.
Recuerde que por defecto, ADO crea cursores de lado servidor. Para que la conexión le cree
todos los cursores de lado cliente basta ejecutar la instrucción:
MiConexion.CursorLocation = adUseClient
Este valor debe establecerlo antes de crear la conexión. De esta forma, todos los cursores
creados con esa conexión serán de lado cliente o lado servidor, según haya elegido. Pero
muchas veces sería ideal que unos recordsets tuvieran el cursor de un tipo y otros de otro.
Los recordsets también tienen esta propiedad, por lo que puede elegir el lado deseado para
cada recordset utilizando esta propiedad aplicada no a la conexión, sino al recordset.
El número de registros que el servidor envía al cliente, cuando el cursor es de lado servidor, se
controla mediante la propiedad CacheSize del recordset. Lo verá más adelante.
Propiedad DefaultDatabase
Establece la base de datos predeterminada para un objeto Connection. Es un string con el
nombre de la base de datos por defecto de esa conexión. Solamente es válida con aquellos
proveedores que permiten varias bases de datos por conexión.
IsolationLevel
Esta propiedad afecta al comportamiento de un objeto Connection durante una transacción.
Una vez establecida esta propiedad, solamente será efectiva cuando se invoque el método
BeguinTrans. Vea la ayuda para mayor información de los valores posibles.
Propiedad Mode,
Establece los permisos disponibles para modificar datos en un objeto Connection.
AdModeShareDenyNone Impide que otros abran una conexión con cualquier tipo de
permiso.
Sólo puede establecer la propiedad Mode cuando el objeto Connection está cerrado. Cuando
se usa en un objeto Connection del lado del cliente, la propiedad Mode sólo se puede
establecer a adModeUnknown.
Propiedad Provider
Es un string que indica el nombre del proveedor de un objeto Connection. Si no se especifica
ningún proveedor, la propiedad tendrá el valor predeterminado MSDASQL (Proveedor de
Microsoft OLE DB para ODBC).
Propiedad State
Devuelve el estado del objeto Connection: abierto (adStateOpen = 1) o cerrado
(adStateClosed = 0).
Método Cancel
Cancela la ejecución de una llamada asíncrona pendiente a un método Execute u Open.
Sintaxis NombreConection.Cancel
El método Cancel se utiliza para terminar la ejecución de una llamada asíncrona a un método
Execute o Open (es decir, el método fue invocado con la opción adAsyncConnect,
adAsyncExecute o adAsyncFetch). Cancel devolverá un error de ejecución si no se utilizó
adAsyncExecute en el método que quiere terminar.
Close, método
Cierra el objeto Connection.
Sintaxis NombredelObjetoConnection.Close
Constante Descripción
Indica que el proveedor tiene que evaluar CommandText como
adCmdText
definición textual de un comando, como una instrucción SQL.
Indica que ADO tiene que generar una consulta SQL para devolver
adCmdTable
todas las filas de la tabla mencionada en CommandText.
Indica que el proveedor tiene que devolver todas las filas de la
adCmdTableDirect
tabla mencionada en CommandText.
Indica que ADO tiene que generar una consulta SQL para devolver
adCmdTable
todas las filas de la tabla mencionada en CommandText.
Indica que el proveedor tiene que evaluar CommandText como
adCmdStoredProc
procedimiento almacenado.
adCmdUnknown Indica que el tipo de comando en CommandText es desconocido.
adAsyncExecute Indica que el comando se tiene que ejecutar de forma asíncrona.
Indica que el resto de las filas siguientes a la cantidad inicial
adAsyncFetch especificada en la propiedad CacheSize tiene que ser recuperada
de forma asíncrona.
MiConnection.Open
Cuando se usa un objeto Connection del lado del cliente, el método Open no establece
realmente una conexión con el servidor hasta que se abre un Recordset del objeto Connection.
Colecciones del Objeto Connection
Colección Errors
Contiene todos los objetos Error creados en respuesta a un único fallo relacionado con el
proveedor. Cada objeto Error representa un error específico del proveedor, no un error ADO.
Los errores ADO se exponen al mecanismo de control de excepciones en tiempo de ejecución.
Cuando otra operación ADO genera un error, se borra la colección Errors y el nuevo conjunto
de objetos Error se coloca en la colección Errors. Las operaciones ADO que no generan un
error no tienen ningún efecto sobre la colección Errors. Para borrar manualmente la colección
Errors utilice el método Clear.
Cada objeto Error de la colección, nos dará información sobre un error producido en la
conexión. Sus propiedades son las siguientes:
• Description: Contiene la descripción del error producido (String).
• NativeError: Indica el error devuelto por la base de datos (Long).
• Number: Es el código de error (Long).
• Source: Indica el nombre del objeto o aplicación que ha generado el error (String).
• SQLState: Indica el error SQL estándar asociado.(String).
Debido a que este objeto será de gran utilidad a continuación se incluye un ejemplo de su uso.
Ejemplo del tratamiento de errores:
El resultado de la ejecución es el siguiente:
Private Sub CBConexion_Click()
Dim MiConex1 As ADODB.Connection
Dim MiError As ADODB.Error
On Error GoTo RutErr
Set MiConex1 = New ADODB.Connection
MiConex1.ConnectionString = "Provider=MSDAORA.1;Password=tiger;User
ID=EScot;Data Source=MADRID;Persist Security Info=True"
MiConex1.Open
Exit Sub
RutErr:
For Each MiError In MiConex1.Errors
MsgBox ("Error VB:" & MiError.Number & vbCrLf _
& "Error Oracle:" & MiError.NativeError & vbCrLf _
& "Error SQL:" & MiError.SQLState & vbCrLf _
& "Generado Por:" & MiError.Source & vbCrLf _
& "Descripción:" & MiError.Description)
Next
End Sub
Como puede observarse, algunas de las propiedades no devuelven los valores esperados:
NativeError vale 0 cuando debería valer –1017, que es el error asociado de Oracle. Aún así
podemos capturar el código del error desde la cadena de caracteres description. Con este
comentario se pretende sugerir que se realicen pruebas con el proveedor de datos que
vayamos a utilizar para conocer su comportamiento respecto a este objeto error y dónde nos
devuelve los códigos.
Colección Properties
Las propiedades dinámicas están definidas por el proveedor de los datos y aparecen en la
colección Properties del objeto ADO apropiado. Por ejemplo, una propiedad específica del
proveedor puede indicar si un objeto Recordset acepta transacciones o actualizaciones. Estas
propiedades adicionales aparecerán como objetos Property en la colección Propiedades de
dicho objeto Recordset. A las propiedades dinámicas se les puede hacer referencia sólo a
través de la colección, utilizando la sintaxis Objeto.Properties(0) u
Objeto.Properties("Name").
Propiedad Bookmark
Devuelve un marcador que identifica unívocamente al registro actual de un objeto Recordset o
establece el registro actual de un objeto Recordset al registro identificado por un marcador
válido. El valor del Bookmark hay que introducirlo en una variable tipo Variant.
Propiedad CacheSize
Indica el número de registros del objeto Recordset que están en la memoria caché local. Es un
Long de lectura y escritura. El valor predeterminado es 1.
Esta propiedad nos permite conocer cuantos registros están en la memoria local. Si ponemos
esta propiedad por ejemplo a 10, al abrir la primera vez el objeto Recordset, el proveedor
recupera los 10 primeros registros en la memoria local. A medida que se desplaza por el objeto
Recordset, el proveedor devuelve los datos desde el búfer de memoria local. Tan pronto como
pasa del último registro de la memoria caché, el proveedor recupera los 10 registros siguientes
desde el origen de datos y los carga en la memoria caché.
Los registros recuperados desde la memoria caché no reflejan los cambios concurrentes que
hagan otros usuarios en el origen de datos. Para forzar una actualización de todos los datos en
la memoria caché, debe usarse el método Resync.
Propiedad MaxRecords
Indica el número máximo de registros que se devuelven a un Recordset desde una consulta.
Es un Long y el valor predeterminado es 0, que significa sin límite (Obtienen todos los
registros). Esta propiedad es de lectura y escritura cuando el recordset está cerrado, y
solamente de lectura cuando está abierto.
Esta propiedad debe usarse solamente cuando se prevé que se pueden obtener un número
muy grande de registros. Es prudente tomar medidas frente a aquellas operaciones en las que
el ordenador pueda meterse en un proceso excesivamente largo o que ocupe más recursos de
los disponibles. Estas cosas son las que suelen “colgar” al ordenador y en las que es muy
frecuente echarle luego la culpa a Windows Si estamos frente a una base de datos con todos
los datos de los afiliados a la Seguridad Social, no es del todo prudente crear un recordset
mediante esta sentencia:
A nadie se le ocurriría, pero puede surgir involuntariamente cuando ese acceso se realiza
desde un puesto de operación público (Acceso desde Internet por ejemplo). Con la propiedad
MaxRecords puede limitar el número de registros obtenidos. Posiblemente no llegue a obtener
el dato deseado, y se vea en la obligación de realizar la misma consulta sucesivas veces hasta
encontrarlo.
Propiedad CursorType
Indica el tipo de cursor que se usa en un objeto Recordset. Es de lectura y escritura si el
recordset está cerrado, y solo de lectura si está abierto. Puede tomar uno de los siguientes
valores:
Propiedad LockType
Indica el tipo de bloqueo que se pone en los registros durante el proceso de edición. Establece
también si el recordset se actualiza registro a registro o por lotes. Este último sistema permite
realizar varios cambios en el recordset y mantenerlos en la caché durante cierto tiempo, y
proceder a la actualización de todos los cambios pendientes en una sola operación. Esto es
muy importante cuando se está trabajando con una base de datos situada en un servidor con
un acceso lento (conexión vía Internet, por ejemplo)
Propiedad EditMode
Indica el estado de modificación del registro actual. Es solamente de lectura. Devuelve uno de
las siguientes constantes:
Propiedad Filter
Esta propiedad solamente la tienen los recordset ADO. Y es que ADO presupone que está
obteniendo datos de una base de datos alojada en un servidor y que la comunicación entre
servidor y cliente puede ser especialmente lenta. Mediante Filter puede descartar registros que
no cumplan una determinada condición. En realidad lo que hacemos mediante Filter es crear
un nuevo Recordset a partir de otro Recordset.
La propiedad Filter se utiliza también para actuar sobre determinados registros en varios
métodos del recordset (Resync, Save, …) pero no se va a explicar en este manual la
explicación de la utilización de esta propiedad en esos métodos, ya que el nivel del
programador que utiliza esos recursos debe ser elevado. Le reservamos por tanto la
posibilidad de conocerlo directamente desde la ayuda de Visual Basic, que en este caso es
bastante buena.
De momento lo que vamos a hacer con Filter es crear un nuevo recordset ¿Por qué no
creamos directamente el nuevo recordset utilizando una sentencia SQL que lleve implícito ese
filtro?
Personalmente no me gusta utilizar la propiedad Filter, y prefiero crear un nuevo recordset.
Creo que solamente lo he usado para rellenar un MSHFlexGrid con parte de los datos del
recordset que uso en una parte de la aplicación. Veamos un ejemplo:
‘Este es el recordset que uso para muchas cosas dentro de la aplicación. Ahora quiero
presentar en un MSHFlexGrid solamente los datos de los autores de nacionalidad española.
Filtro el recordset anterior utilizando un criterio de igualdad de un campo: Nacionalidad
‘Y cuando queremos presentar todos los autores, basta con poner la línea:
La propiedad Filter puede mostrar también aquellos registros que han sido manipulados
recientemente, mediante las constantes siguientes:
Propiedad Index
Indica el nombre del índice que se utiliza actualmente en el Recordset. Es un String con el
nombre del índice.
El índice se utiliza para moverse a lo largo del recordset mediante el método Move. El índice
ya debe estar creado en la tabla de la base de datos.
Al utilizar un índice, el orden de los registros se cambia al orden establecido en ese índice. Por
lo tanto, los valores obtenidos anteriormente por la propiedad AbsolutePosition cambiarán
completamente.
No todos los proveedores de datos aceptan la propiedad Index. Puede comprobarlo mediante
el método Supports.
Propiedad MarshalOptions
Esta propiedad se usa cuando estamos trabajando con cursores lado cliente. En este caso,
como vimos más atrás, los registros del recordset están en el equipo cliente. Todas las
operaciones realizadas sobre el recordset se realizan en el cliente, por lo tanto llegará el
momento en que habrá que actualizar en el servidor los datos que hayamos modificado en el
recordset que está en el equipo cliente. Mediante esta propiedad podemos hacer que se
envíen al servidor todos los registros (filas) o solamente los que han cambiado. Acepta estas
dos constantes:
Esta propiedad puede mejorar el rendimiento de la aplicación para aquellos casos en los que
se use un canal de comunicación lento.
Propiedad PageSize
Indica cuántos registros constituyen una página del objeto Recordset. Es de lectura y escritura.
Devuelve un Long y su valor predeterminado es 10.
Esta propiedad permite determinar cuántos registros componen una página lógica de datos. Al
establecer un tamaño de página, puede utilizar la propiedad AbsolutePage y se moverá al
primer registro de una página específica. Esto es útil en las situaciones de servidor Web
cuando se desea permitir que el usuario pase páginas de datos y vea cierto número de
Propiedad PageCount
Indica cuántas páginas de datos contiene el objeto Recordset. Es solamente de lectura.
Devuelve un Long. Si el objeto Recordset no admite esta propiedad, el valor será -1 para
indicar que no se puede determinar el valor de PageCount.
Propiedad AbsolutePage
Especifica en qué página reside el registro actual. Es de lectura y escritura. Devuelve un Long
o una de las siguientes constantes:
AdPosBOF El puntero del registro actual está al comienzo del archivo (es decir, la
propiedad BOF tiene el valor True).
AdPosEOF El puntero del registro actual está al final del archivo (es decir, la
propiedad EOF tiene el valor True).
Propiedad RecordCount
Indica el número actual de registros de un objeto Recordset. Devuelve un Long
Es posible que esta propiedad no la permita el proveedor de datos, o que no pueda llegar a
averiguarse, ya que dependiendo del tipo de cursor utilizado puede que no suministre ese
dato.
Propiedad Source
Devuelve la tabla, consulta o sentencia SQL utilizado en el método Open para crear el
recordset. Es un String.
Propiedad State
Indica el estado (abierto, cerrado, proceso de ejecución) en el que se encuentra el recordset.
Devuelve uno de los siguientes valores:
Constante Descripción
Valor predeterminado. Indica que el objeto está
adStateClosed
cerrado.
adStateOpen Indica que el objeto está abierto.
Indica que el objeto Recordset se está
adStateConnecting
conectando.
Indica que el objeto Recordset está ejecutando
adStateExecuting
un comando.
Indica que se está obteniendo el conjunto de filas
adStateFetching
del objeto Recordset.
Puede tener una combinación de valores. Por ejemplo, si se está ejecutando una instrucción,
esta propiedad tendrá un valor combinado de adStateOpen y adStateExecuting.
Propiedad Status
Esta propiedad se refiere al registro actual. Indica el estado de este registro respecto a las
operaciones de actualización por lotes u otras operaciones masivas. No es una propiedad que
se use todos los días. Vea la ayuda para mas detalles.
Unique Table especifica la tabla sobre la que se permite realizar modificaciones de datos
(Insertar o actualizar), en el caso de que el recordset se haya creado mediante una operación
JOIN
Estas funcionalidades se le pasan como parámetro mediante una de las siguientes constantes:
Nota Aunque el método Supports puede devolver True para una funcionalidad determinada,
eso no garantiza que el proveedor pueda hacer que la característica esté disponible bajo
cualquier circunstancia. El método Supports devuelve simplemente si el proveedor puede
El valor devuelto por el método Supports dependerá del tipo de recordset elegido. En la
siguiente tabla puede ver el tipo de recordset y las constantes para las que va a devolver True:
AdOpenForwardOnly Ninguna
AdOpenKeyset adBookmark, adHoldRecords, adMovePrevious, adResync
AdOpenDynamic AdMovePrevious
AdOpenStatic adBookmark, adHoldRecords, adMovePrevious, adResync
Método Open
Es el método que ABRE el recordset. Este método es el que busca los registros que han de
rellenar el recordset.
Un recordset puede abrirse partiendo de una conexión ya abierta. Pero también puede
crearse directamente, sin abrir previamente la conexión. Al final, deberá aportar todos los
datos necesarios para determinar en que base de datos se abre ese recordset. Sobre que
tabla, consulta o sentencia SQL., que tipo de cursor va a ser, etc. Lo que ocurre es que ADO
es muy flexible y nos permite hacerlo de varias formas, aunque todas ellas conducen a lo
mismo.
Source (Opcional) Es el nombre de una tabla, consulta o sentencia SQL de la cual se obtienen
los registros del Recordset.
CursorType (Opcional). Un valor que determina el tipo de cursor que el proveedor debe usar
al abrir el Recordset. Puede ser una de las siguientes constantes
LockType (Opcional). Un valor que determina el tipo de bloqueo que debe usar el proveedor al
abrir el Recordset. Con este parámetro se le indica también si debe hacer las actualizaciones
registro a registro o en bloque. Puede ser una de las siguientes constantes
AdCmdText Indica que el proveedor debe evaluar Source como una definición
textual de un comando.
AdCmdTable Indica que ADO debe generar una consulta SQL para devolver
todaslas filas de la tabla nombrada en Source.
AdCmdTableDirect Indica que el proveedor debe devolver todas las filas de la
tabla nombrada en Source.
AdCmdStoredProc Indica que el proveedor debe evaluar Source como un
procedimiento almacenado
AdCmdUnknown Indica que el tipo de comando del argumento Source es
desconocido.
AdCmdFile Indica que el Recordset guardado se debe restaurar desde el
archivo nombrado en Source.
AdAsyncExecute Indica que Source se debe ejecutar de forma asíncrona.
AdAsyncFetch Indica que, tras alcanzar la cantidad inicial especificada en la
propiedad Initial Fetch Size, las filas restantes deben
buscarse de forma asíncrona. Si se requiere una fila que no se
ha encontrado, se bloqueará el subproceso principal hasta que
se disponga de la fila solicitada.
AdAsyncFetchNonBlocking Indica que el subproceso principal nunca se bloquea
durante la búsqueda. Si no se encuentra la fila
solicitada, la fila actual se desplaza automáticamente
al final del archivo.
Habrá observado que hemos remarcado que el método Open ABRE un recordset. No lo
crea. El recordset debe estar creado previamente. ¿Qué cuando se crea? Mediante la
instrucción:
Set MiRecordset = New ADODB.Recordset
Metodo Requery
Actualiza los datos de un objeto Recordset volviendo a ejecutar la consulta utilizada para
abrirlo. Se obtiene el mismo resultado que si se cerrara el recordset y se volviera a abrir.
Optiones Opcional. Máscara de bits que indica opciones que afectan a esta operación. Si el
valor de este parámetro está establecido a adAsyncExecute, esta operación se ejecutará de
forma asíncrona y se emitirá un evento RecordsetChangeComplete cuando concluya.
Método Resync
Actualiza los datos del objeto Recordset actual. Este método, a diferencia del método
Requery, no vuelve a ejecutar el comando de creación del recordset, sino que lee los registros
existentes en el recordset para actualizar su valor, pero no presenta aquellos registros que
hubieran sido creados con posterioridad a la apertura del recordset. Es más rápido que el
método Requery, y en muchos casos solamente nos interesa actualizar los registros sobre los
que estamos trabajando.
Los parámetros FieldList y Values son opcionales. En caso de ponerlos, FieldList serán los
nombres de los campos a los que se les va a poner un valor, y Values son los valores de cada
uno de estos campos. El orden nombre - valor debe mantenerse estrictamente.
Siempre recomendaré que, en vez de meter los datos mediante estos parámetros, se metan
posteriormente linera a línea, tal como se hizo siempre con los recordsets
NombreDelRecordset!NombredelCampo = ValorDelCampo
ó
NombreDelRecordset(“NombredelCampo”) = ValorDelCampo
Esta segunda forma es necesaria cuando el nombre del campo tiene espacios. Nunca es
recomendable poner espacios en los nombres de campos, pero en caso de que existan,
debe optar por utilizar la sintaxis segunda, con los paréntesis y comillas dobles.
No siempre se puede utilizar el método AddNew. Puede comprobar si se puede utilizar, usando
el método Supports visto anteriormente.
El método AddNew convierte a este registro recién creado en registro actual. Pero este registro
solamente existe en el recordset. Para introducir los datos en la base de datos, (Y por lo tanto
en el disco duro) es necesario invocar el método Update una vez introducidos todos los
valores de los campos que deseamos introducir. Con algún tipo de cursor es necesario
también utilizar el método Requery para poder acceder al registro recién creado.
Si se invoca el método AddNew mientras se está editando el registro actual, o durante otra
operación AddNew, ADO invoca automáticamente el método Update para guardar los
cambios. Vea más adelante los métodos Update y UpdateBatch.
Método Update
Guarda los cambios realizados en el registro actual de un objeto Recordset. Se utiliza tanto
para “rematar” una operación de creación de un registro iniciada con AddNew, como para
guardar los nuevos datos del registro actual (Recuerde que en ADO no existe el método Edit,
tal como ocurría en DAO)
.
Sintaxis NombreDelRecordset.Update Fields, Values
En esta sintaxis, Fields y Values son opcionales, y solamente tienen aplicación cuando se trata
de cambiar los valores del registro actual, no de terminar una operación de creación de un
nuevo registro mediante AddNew.
Vuelvo a recomendar lo anterior. Para cambiar los valores de varios campos de un registro,
nos colocaremos sobre ese registro, y sin invocar ningún método, ejecutaremos este código
MiRecordset!Campo1 = Valor1
MiRecordset!Campo2 = Valor2
……….
MiRecordset!CampoN = ValorN
MiRecordset.Update
Pero en ADO pasa una cosa que no pasaba en DAO. Si cambiamos de registro una vez
modificado el valor de un registro, ADO invoca automáticamente el método Update. Por lo
tanto, el código siguiente:
MiRecordset!Campo1 = Valor1
Tendrá el mismo resultado que el anterior cuando cambiemos de registro actual. Esto puede
ser bueno a malo, pero personalmente pienso que no es práctico porque implica tener mucho
más cuidado que en DAO. Hace lo mismo que cuando tenemos unos controles enlazados a
datos mediante un control Data.
MiRecordset!Campo1 = Valor1
Queremos que ese nuevo valor no entre en la base de datos, debemos cancelarlo mediante el
método CancelUpdate.
Método UpdateBatch
Escribe en disco todas las actualizaciones pendientes de proceso por lotes. En ADO un
recordset puede actualizarse registro a registro o por lotes. Todo dependerá de cómo se ha
abierto (Si el valor LockType se ha puesto a AdLockBatchOptimistic)
Método Cancel
Cancela la ejecución del método Open.
Sintaxis NombreDelRecordset.Cancel
El método Cancel solamente puede usarse si el método Open fue invocado con la opción
adAsyncConnect, adAsyncExecute o adAsyncFetch.
Método Delete
Elimina el registro actual o un grupo de registros. Por defecto elimina solamente el registro
actual. Vea la ayuda para ampliar los detalles respecto al parámetro opcional AffectRecords
Método CancelUpdate
Habíamos visto más atrás que el ADO no existe el método Edit. Para modificar un registro
basta con poner una instrucción tal como esta:
MiRecordset!MiCampo = MiNuevoValor
MiRecordset.Update
Sintaxis MiRecordset.CancelUpdate
Recuerde que ADO funciona de forma distinta a DAO con estos métodos de modificación de
los registros. Recuerde que si está en proceso de modificación de un registro (Ha ejecutado
la primera línea del ejemplo anterior) y cambia de registro, por el hecho de cambiar de
registro, ADO invoca automáticamente el método Update.
Método CancelBatch
Cancela una actualización por lotes pendiente. Es similar a la anterior, pero para actualización
por lotes.
Método Clone
Crea un objeto Recordset duplicado a partir de un objeto Recordset existente. Opcionalmente,
puede especificarse que el nuevo recordset sea solamente de lectura
(El objeto rstDuplicate debe estar declarado previamente como objeto ADODB.Recordset)
Método Move
Mueve la posición del registro actual de un objeto Recordset
.
Sintaxis MiRrecordset.Move NumRecords, Start
NumRecords Un valor Long con signo que especifica el número de registros que debe
moverse a partir de la posición del registro actual o del registro especificado en el parámetro
Start, si es que se especifica.
Start Opcional. Un String o Variant cuyo resultado sea un marcador del tipo Bookmark.
Puede utilizar también una de las siguientes constantes:
Tenga en cuenta a la hora de usar los métodos Move que pueden existir Recordsets que no
permiten el movimiento hacia atrás.
Método Find
Busca el primer registro del recordset que satisfaga los criterios especificados en el criterio de
búsqueda. Si se cumple el criterio de búsqueda, la posición del recordset se establece en el
primer registro encontrado; si no, la posición se establece al final del recordset.
start (Opcional) Un marcador tipo BookMark que se utiliza como posición inicial de
la búsqueda.
El operador de comparación de criterio puede ser ">", "<", "=", ">=" , "<=", "<>" (distinto de) o
"like" (coincidencia parcial de cadenas). El valor de comparación puede ser una cadena, un
número en coma flotante o una fecha. Los valores de cadena están delimitados con comillas
sencillas (por ejemplo, "Pais = 'España'"). Los valores de fecha están delimitados con signos
"#" y con formato mm/dd/yy (por ejemplo, "fecha_inicial > #7/22/97#"). Si el operador de
comparación es "like", el valor de la cadena puede contener los caracteres comodín "*" o "_".
(Funcionan de forma idéntica, sustituyendo a cualquier sucesión de caracteres.) No acepta el
carácter “?” (Por ejemplo, "Pais like ‘Es_’" o “Pais Like ‘Es*’ encuentra España y Estonia)
ADO no tiene los métodos FindFirst, FindNext, FindPrevious y FindLast. Deberá emplear el
método Find de forma inteligente para implementar estos otros.
Método Save
Este método permite guardar el contenido de un Recordset en un fichero. Puede ser muy útil
cuando queremos exportar ese recordset hacia otra aplicación.
Si ya existe el fichero le dará un error. Cerciórese que no existe (Mediante la función Dir) y
bórrelo antes de volver a utilizar el método Save.
Método Seek
Este método busca un registro desplazándose por el recordset a lo largo de un índice o un
conjunto de índices. La búsqueda mediante Seek es mucho más rápida que con Find, ya que
la realiza siguiendo el ordenamiento de los registros según un índice.
Para poder usar el método Index es necesario que el proveedor acepte índices en el objeto
recordset. Esto ha llevado al autor a no poder presentar ningún ejemplo de este método, ya
que todas las bases de datos ensayadas no permitían índices. Puede ver si acepta índices
mediante el método Supports:
Método NextRecordset
Para entender este método es necesario explicar previamente como se puede crear un
recordset compuesto.
MiRecordset es un recordset compuesto. Toma datos de dos tablas distintas, pero podría
haberlo hecho solamente de una tabla con una condición distinta en la SELECT.
Puede usar también este recordset para crear un nuevo recordset a partir del primero
MiRecordset2 debe estar declarado como objeto recordset, y creado con la instrucción New:
Set MiRecordset2 = New ADOBD.Recodset
Un objeto Recordset tiene una colección Fields que contiene todos los objetos Field. Cada
objeto Field se corresponde a una columna del Recordset.
Vamos a ver aquí un truco que nos permite ADO. Podemos crear un recordset ¡Sin necesidad
de una base de datos!
Cuando estudiamos el objeto recordset vimos que el recordset se crea con una instrucción
como esta:
Set MiRecordset1 = New ADODB.Recordset
Ahora ya podemos abrir el recordset leyendo los datos desde una base de datos. Utilizamos
para ello el método Open del recordset:
Mediante el método Open lo que hace el recordset es conocer su estructura (Que campos
tiene, propiedades de estos campos, etc) y el valor de cada uno de los campos de sus
registros. ¿Qué pasaría si en vez de abrir el recordset le vamos añadiendo objetos Field a su
colección Fields? Lo hacemos mediante el método Append:
Lo que ocurre es que el recordset ya tiene tres campos, el primero de nombre MiCampo1,
numérico Long, el segundo, un string de 25 caracteres de nombre MiCampo2, y el tercero, de
nombre MiCampo3, una cadena de caracteres de longitud indefinida, terminada en un carácter
nulo. Ya tenemos una estructura de un recordset sin necesidad de haber leído la base de
datos. No es necesario por lo tanto que exista una tabla o consulta almacenada con esa
estructura. Ahora podemos abrir el recordset:
MiRecordset1.Open
Lo abrimos sin pasarle ningún parámetro. Ahora ya está abierto y podemos trabajar con el
como con un recordset cualquiera. Recuerde que al principio está vacío.
MiRecordset1.AddNew
MiRecordset1!MiCampo1 = 34
MiRecordset1!MiCampo2 = "Guía del Estudiante"
MiRecordset1!MiCampo3 = "Hola mi amor" & vbCrLf & "Yo soy tu lobo"
MiRecordset1.Update
Ya tenemos un registro dentro del recordset. Podemos introducirle tantos registros como
queramos, y luego movernos por el recordset mediante los métodos Movexxxx. Ahora
podremos leer el contenido del registro actual:
Label1 = MiRecordset1!MiCampo1
Label2 = MiRecordset1!MiCampo2
Label3 = MiRecordset1!MiCampo3
El resultado del código de el ejemplo se traducirá en algo como esto:
Es una idea, pero piense que esto no regala nada. El espacio de memoria consumido será
similar a si usa variables. Pero posiblemente estará más cómodo y más inteligible su código.
Método Append
Agrega un campo a una colección Fields de un Recoprdset.
Name Un String con el nombre del nuevo objeto Field, que tiene que ser único dentro de la
coleccón Fields.
Type Tipo de datos que va a contener ese campo. Puede tomar uno de estos valores:
Se une en una instrucción OR lógica con otro tipo para indicar que los
adArray
datos son una matriz segura de ese tipo (DBTYPE_ARRAY).
adBigInt Un entero con signo de 8 bytes (DBTYPE_I8).
adBinary Un valor binario (DBTYPE_BYTES).
adBoolean Un valor Boolean (DBTYPE_BOOL).
Se une en una instrucción OR lógica con otro tipo para indicar que los
adByRef
datos son un puntero a los datos del otro tipo (DBTYPE_BYREF).
Una cadena de caracteres terminada en nulo (Unicode)
adBSTR
(DBTYPE_BSTR).
adChar Un valor de tipo String (DBTYPE_STR).
Un valor de tipo Currency (DBTYPE_CY). Un valor Currency es un
adCurrency número de coma fija con cuatro dígitos a la derecha del signo decimal.
Se almacena en un entero con signo de 8 bytes en escala de 10.000.
Un valor de tipo Date (DBTYPE_DATE). Un valor Date se almacena
como un valor de tipo Double; la parte entera es el número de días
adDate
transcurridos desde el 30 de diciembre de 1899 y la parte fraccionaria
es la fracción de un día.
adDBDate Un valor de fecha (aaaammdd) (DBTYPE_DBDATE).
adDBTime Un valor de hora (hhmmss) (DBTYPE_DBTIME).
Una marca de fecha y hora (aaaammddhhmmss más una fracción de
adDBTimeStamp
miles de millones) (DBTYPE_DBTIMESTAMP).
Un valor numérico exacto con una precisión y una escala fijas
adDecimal
(DBTYPE_DECIMAL).
adDouble Un valor de coma flotante de doble precisión (DBTYPE_R8).
adEmpty No se ha especificado ningún valor (DBTYPE_EMPTY).
adError Un código de error de 32 bits (DBTYPE_ERROR).
adGUID Un identificador único global (GUID) (DBTYPE_GUID).
Un puntero a una interfaz Idispatch de un objeto OLE
adIDispatch
(DBTYPE_IDISPATCH).
adInteger Un entero firmado de 4 bytes (DBTYPE_I4).
DefinedSize Un Long que define el tamaño del campo si fuese necesario. (Por ejemplo
para un string)
Attrib (Opcional). Especifica los atributos del campo a añadir. Puede tomar estos
valores:
Método Delete
Teóricamente elimina un objeto de la colección Fields.
Field Un Variant que designa el objeto Field que se va a eliminar. Este parámetro tiene
que ser el nombre del objeto Field; no puede ser una posición ordinal o el propio objeto Field.
Comentarios
La llamada al método Fields.Delete en un Recordset abierto provoca un error de ejecución.
(Como ha ocurrido en otras ocasiones, al autor le ha sido imposible ejecutar este método con
los resultados esperados)
Método Item
Método Refresh
Aunque la colección Fields tiene este método, la verdad es que no tienen efectos visibles
sobre esa colección.
Propiedad Count
Devuelve el número de campos de la colección Fields. Es un Long.
Utilice un objeto Command para consultar una base de datos y obtener registros en un objeto
Recordset, para añadir o eliminar registros, ejecutar una operación de manejo masivo de datos
o para manipular la estructura de una base de datos.
Propiedad ActiveConnection
Indica a qué objeto Connection pertenece actualmente el objeto Command. Es un string con el
nombre de la conexión.
Propiedad CommandText
Contiene el texto del comando que se quiere emitir al proveedor. Es un string. Suele ser una
instrucción SQL, un nombre de tabla o un procedimiento almacenado, o cualquier otra
instrucción que reconozca el proveedor. El valor predeterminado es una cadena vacía.
Propiedad CommandTimeout
Especifica el intervalo de espera para que se ejecute un comando antes de que finalice el
intento y se genere un error. Es un Long que indica en segundos ese tiempo. El valor
predeterminado es 30.
Valores posibles
Propiedad State
Describe el estado del objeto: abierto o cerrado. Devuelve un Long o una constante:
adStateClosed o adStateOpen
Sintaxis
Para un Command que devuelva filas:
Parameters Opcional. Una matriz Variant con los valores de los parámetros pasados con una
instrucción SQL. (Los parámetros de salida no devuelven valores correctos cuando se pasan
en este argumento).
Método Cancel
Cancela la ejecución de una llamada asíncrona pendiente al método Execute
Utilice el método Cancel para terminar la ejecución de una llamada asíncrona a un método
Execute (es decir, el método fue invocado con la opción adAsyncExecute o adAsyncFetch).
Comandos parametrizados.
Los objetos Command pueden utilizar parámetros. De esta forma, podemos construir una
consulta utilizando la interrogación (?) como comodín. Así cada vez que ejecutemos el
comando, V.B. se encargará de sustituir el comodín por los parámetros asociados a dicho
command. Además podemos utilizar los parámetros para recoger los valores devueltos por un
Procedimiento almacenado en la base de datos. Para entender mejor este tipo de consultas
primero veremos qué es el objeto parameter.
Declaraciones
Dim ConexBDPrensa As ADODB.Connection
Dim RsBDPrensa1 As ADODB.Recordset
Dim StrIntroducir As String, NumeroDocumento as long
Rem Se introduce en una variable tipo String una instrucción para añadir un nuevo registro
Rem Esa instrucción se va a ejecutar desde el objeto Connection mediante su método
Execute
Rem Observe que los valores tipo string introducidos (TbXXX) van entre comilla simple
Rem Se ejecuta esa instrucción desde el objeto Connection ConexBDPrensa
ConexBDPrensa.Close
Rem Aquí termina la operación de crear un nuevo registro
MsgBox "Documento enviado"
Este es el código real de una aplicación que introduce los datos el resumen de prensa diario en
una base de datos. Se introduce un nuevo registro en la tabla INT_DOCUMENTOS. El
resumen de prensa es un fichero .Tiff de nombre TbNombFichTIF que se mete en una carpeta
del servidor mediante FTP, y para su loccalización y presentación en una página Web es
necesario introducir su nombre y Path y otros datos en una base de datos. Los campos que se
introducen y los valores de cada uno son:
Campo Valor
Esta forma de introducir los datos, método que los lingüistas especializados en la jerga
informática llaman “a capón”, es la que nunca falla. Exige un poco de código, con muchas
probabilidades de equivocarse, pero muchas veces se prefiere esta forma de meter datos a
utilizar el método AddNew. Tiene la gran ventaja de que la acepta cualquier base de datos,
independientemente de donde esté el cursor. Habrá observado que utilizamos el método
Execute del objeto Connection. Y así funciona perfectamente. Vamos a hacer lo mismo, pero
introduciendo la cadena de caracteres un objeto Command, (Que pertenece al mismo objeto
Connection sobre el que ahora hemos ejecutado el Execute) y vamos a ejecutar el Execute de
ese Command. ¿Se da cuenta que estamos haciendo lo mismo? El nuevo código creado a
partir del anterior es el siguiente:
MiComando.Execute
ConexBDPrensa.Close
ADO le permite hacer las cosas de maneras muy distintas, pero siempre debe aportar la
misma información. En este caso ha visto que el objeto Command no hace falta para nada.
Vamos a ver ahora cómo haríamos esto mismo con el método AddNew.
Luego lo creamos:
Set RsBDPrensa = New ADODB.Recordset
ConexBDPrensa.CursorLocation = adUseClient
Abrimos el Recordset:
RsBDPrensa.Open "Int_Documentos", ConexBDPrensa, adOpenDynamic, adLockOptimistic
Cerramos el recordset.
RsBDPrensa.Close
Cerramos la conexión
ConexBDPrensa.Close
Nota 1. – Muchos programadores se rinden cuando ven que no les funciona los métodos
AddNew / Update para introducir nuevos datos. Cierto es que cada base de datos se
comporta de forma distinta respecto a este método. Pero antes de rendirse y usar el código
“a capón” intente ver como tienen la propiedad CursorLocation, el tipo de recordset abierto y
el tipo de bloque elegido (Recuerde que por defecto es de solo lectura). Eso sí, el método “a
capón” funciona siempre (Excepto que sea solo lectura), independientemente del bloqueo y
del tipo de cursor
El control Data para ADO es el “Microsoft ADO data control 6.0 (OLEDB)” que se encuentra
en Proyecto | Componentes. La apariencia es similar a la del Data de DAO
Hagamos un repaso de sus propiedades. Veremos solamente aquellas que son específicas de
ADO:
Propiedad BOFAction.
Establece la forma de proceder cuando llega a la fila anterior a la primera. Toma uno de estos
valores:
Propiedad CommandType
Es idéntica a la misma propiedad del objeto Command. Acepta los valores:
Propiedad ConnectionString
Esta propiedad ya le hemos visto más atrás. Es la cadena de conexión con la base de datos.
Propiedad CursorLocation
Propiedad CursorType
Es la misma que para el objeto Recordset. Acepta los valores:
1 – adOpenKeyset
2 - adOpenDynamic
3 – adOpenStatic
Propiedad EOFAction
Propiedad LockType
Propiedad MaxRecords
Es similar a la del Objeto Recordset. Establece el número de filas que obtiene en su recordset
asociado.
Propiedad Mode.
Igual a la misma propiedad del objeto Recordset
Propiedades Password
Establece la contraseña para crear la cadena de conexión durante la creación del objeto
Recordset asociado. Esta contraseña es la contraseña del usuario en la base de datos.
Propiedad UserName
Establece el nombre del usuario. Debe ser uno de los usuarios registrados en la base de datos.
Esta propiedad es de lectura y escritura. El valor de la propiedad Password debe ser el
asociado a este usuario.
Propiedad RecordSource
Es una cadena de caracteres con el nombre de una tabla o una sentencia SQL que devuelve
filas.
UpdateControls
Actualiza la información de los controles enlazados a datos. No existe el método
UpdateRecords.
Refresh
Vuelve a construir el recordset. Es idéntico al del control Data de DAO.
Vistas ya las propiedades y métodos del control Adodc, vamos a ver un poco como funciona y
cuales son sus diferencias con el control data de DAO
El Adodc puede enlazar una base de datos a los típicos controles enlazados (Label, TextBox)
usando la tecnología ADO. Los demás controles enlazados no tienen un comportamiento igual
con el Adodc, Control Data o RDODataControl. En la siguiente lista puede ver que controles
trabajan con uno u otro control Data.
Con este capítulo creo que ya tienen conocimientos suficientes para empezar a trabajar con
ADO, y por la tanto, ya tiene permiso para aprender a programar con esta tecnología. Le
recomiendo paciencia, y sobre todo no tener miedo a esta tecnología. Y como se dijo al
principio, úsela siempre que tenga que usar una base de datos instalada en un servidor y
conectada al usuario a través de una red de área local. En el próximo capítulo verá como se
enlazan un cliente con el servidor SQL Server.
De cualquier forma no olvide la tecnología DAO para sus pequeñas aplicaciones, con la base
de datos en el mismo ordenador que la aplicación. Personalmente creo que es mucho más
rápida y más sencilla.
Suerte.
Agradecimientos. En este capítulo participó activamente mi alumno del CEU César Moreno
Fernández.