sql >> Base de Datos >  >> RDS >> Access

¿Cómo se comunica Access con las fuentes de datos ODBC? Parte 2

ACTUALIZACIÓN: Se agregaron algunas aclaraciones más sobre el significado de SQLExecute y cómo Access maneja las consultas preparadas. ¡Gracias Bob!

¿Qué hace Access cuando navegamos y miramos registros en una tabla vinculada ODBC?

En la segunda parte de nuestra serie de seguimiento ODBC, nuestro enfoque se centrará en el impacto que tienen los tipos de conjuntos de registros dentro de una tabla vinculada ODBC. En el último artículo, aprendimos cómo activar el seguimiento SQL de ODBC y ahora podemos ver el resultado. Si ha jugado un poco con él, es posible que haya notado que su consulta de Access y las declaraciones ODBC SQL que genera Access no se parecen mucho. También proporcionaremos una mirada en profundidad a cómo los tipos influyen en el comportamiento de las consultas SELECT, y también veremos diferentes variaciones de conjuntos de registros, como instantáneas y conjuntos dinámicos.

Si desea continuar, puede usar la base de datos de muestra que se proporciona aquí.

Efecto de los tipos de conjuntos de registros en una consulta SELECT

Los tipos de conjuntos de registros tienen un gran efecto en cómo Access se comunicará con las fuentes de datos ODBC. Es posible que haya notado que en una vista de diseño de formulario o en una vista de diseño de consulta, puede establecer el tipo de conjunto de registros. De forma predeterminada, se establece en Dynaset .

En VBA, tenemos algunas opciones más, pero no nos preocuparemos por eso por ahora. Empecemos por entender qué es exactamente Dynaset y Snapshot significa primero. Comenzaremos con el tipo de uso menos común, Snapshot primero.

Conjuntos de registros de tipo instantánea

Snapshot es bastante simple Básicamente significa que tomamos una instantánea del resultado en el momento de la ejecución de la consulta. Normalmente, esto también significa que Access no puede actualizar el resultado. Sin embargo, veamos cómo Access consulta el origen con un conjunto de registros basado en instantáneas. Podemos crear una nueva consulta de Access así:

El SQL como podemos ver en la vista SQL de la consulta de Access es:

SELECT Cities.*
FROM Cities;
Ejecutaremos la consulta y luego miraremos el sqlout.txt expediente. Aquí está el resultado, formateado para facilitar la lectura:

SQLExecDirect:
SELECT
   "CityID"
  ,"CityName"
  ,"StateProvinceID"
  ,"Location"
  ,"LatestRecordedPopulation"
  ,"LastEditedBy"
  ,"ValidFrom"
  ,"ValidTo"
FROM "Application"."Cities"
Hubo pocas diferencias entre lo que escribimos en la consulta de Access en comparación con lo que Access envió a ODBC, que analizaremos.

  1. Access calificó la tabla con el nombre del esquema. Obviamente, en el dialecto SQL de Access, eso no funciona de la misma manera, pero para el dialecto SQL ODBC, es útil asegurarse de que estamos seleccionando de la tabla correcta. Eso se rige por SourceTableName propiedad.
  2. Acceso amplió el contenido de Cities.* en una lista enumerada de todas las columnas que Access ya conoce según los Fields colección del TableDef subyacente objeto.
  3. Acceso usó el " para citar los identificadores, que es lo que espera el dialecto SQL de ODBC. Aunque tanto Access SQL como Transact-SQL usan corchetes para citar un identificador, esa no es una sintaxis legal en el dialecto ODBC SQL.

Entonces, aunque solo hicimos una consulta de instantánea simple seleccionando todas las columnas para una tabla, puede ver que Access realiza una gran transformación en el SQL entre lo que coloca en la vista de diseño de consulta de Access o la vista SQL versus lo que Access realmente emite a los datos fuente. En este caso, sin embargo, es principalmente sintáctico, por lo que no hay una diferencia real en la instrucción SQL entre la consulta de Access original y la instrucción SQL ODBC.

El seguimiento también agregó SQLExecDirect al comienzo de la instrucción SQL. Regresaremos a eso una vez que hayamos visto algunos otros ejemplos.

Conjuntos de registros tipo Dynaset

Usaremos la misma consulta pero cambiaremos la propiedad a su valor predeterminado, Dynaset .
Ejecutarlo de nuevo y veremos qué obtenemos del sqlout.txt . Nuevamente, está formateado para facilitar la lectura:

SQLExecDirect:
SELECT
  "Application"."Cities"."CityID"
FROM "Application"."Cities"

SQLPrepare:
SELECT
   "CityID"
  ,"CityName"
  ,"StateProvinceID"
  ,"Location"
  ,"LatestRecordedPopulation"
  ,"LastEditedBy"
  ,"ValidFrom"
  ,"ValidTo"
FROM "Application"."Cities"
WHERE "CityID" = ?

SQLExecute: (GOTO BOOKMARK)

SQLPrepare:
SELECT
   "CityID"
  ,"CityName"
  ,"StateProvinceID"
  ,"Location"
  ,"LatestRecordedPopulation"
  ,"LastEditedBy"
  ,"ValidFrom"
  ,"ValidTo"
FROM "Application"."Cities"
WHERE "CityID" = ?
   OR "CityID" = ?
   OR "CityID" = ?
   OR "CityID" = ?
   OR "CityID" = ?
   OR "CityID" = ?
   OR "CityID" = ?
   OR "CityID" = ?
   OR "CityID" = ?
   OR "CityID" = ?

SQLExecute: (MULTI-ROW FETCH)

SQLExecute: (MULTI-ROW FETCH)
¡Vaya, pasan muchas cosas! Esto definitivamente es más hablador que el conjunto de registros de tipo instantánea. Repasémoslos uno por uno.

El primero solo selecciona el CityID columna. Esa es la clave principal de la tabla, pero lo que es más importante, ese es el índice que Access está usando en su lado. Eso será importante cuando estudiemos las vistas más adelante. Access usa esta consulta para obtener las claves y la usa para completar otras consultas más adelante, como veremos.

La segunda declaración está más cerca de la consulta de instantánea original, excepto que ahora tenemos un nuevo WHERE cláusula de filtrado en el CityID columna. De eso podemos ver que es una búsqueda de una sola fila. Podemos usar las claves que obtuvimos de la primera consulta y recopilar el resto de columnas en esta consulta. Siempre que se ejecute esa instrucción preparada, verá un SQLExecute: (GOTO BOOKMARK) .

Pero eso sería ineficiente si tuviéramos que hacer esto para todas las filas... Y ahí es donde entra la siguiente consulta. La tercera declaración es similar a la segunda pero tiene 10 predicados. Esta consulta preparada se ejecuta con cada SQLExecute: (MULTI_ROW FETCH) . Entonces, lo que esto significa es que cuando cargamos un formulario o una hoja de datos o incluso abrimos un conjunto de registros en código VBA, Access usará la versión de una sola fila o la versión de múltiples filas y completará los parámetros usando las claves que obtuvo de la primera consulta.

Obtención y resincronización en segundo plano

Por cierto, ¿alguna vez ha notado que cuando abre un formulario o una hoja de datos, no puede ver la "X de Y" en la barra de navegación?

Eso se debe a que Access no puede saber cuántos hay hasta que haya terminado de recopilar los resultados de la primera consulta. Es por eso que a menudo puede encontrar que es muy rápido abrir una consulta que devuelve una gran cantidad de datos. Solo obtiene una vista previa de una pequeña ventana de todo el conjunto de registros mientras Access obtiene las filas en segundo plano. Si hace clic en el botón "Ir al último", es posible que descubra que congela el acceso. Tendría que esperar hasta que haya terminado de obtener todas las claves en la primera consulta antes de que podamos ver la "X de Y" en la barra de navegación.

Por lo tanto, puede apreciar cómo Access puede proporcionar la ilusión de abrir rápidamente incluso un conjunto de registros grande cuando usamos un conjunto de registros de tipo dynaset y suele ser una buena experiencia para el usuario.

Finalmente, debemos tener en cuenta que obtuvimos 3 tipos diferentes de ejecuciones, SQLExecDirect , SQLPrepare y SQLExecute . Puede ver que con el primero, no tenemos ningún parámetro. La consulta es simplemente tal cual. Sin embargo, si es necesario parametrizar una consulta, primero debe prepararse a través de SQLPrepare y luego ejecutado con SQLExecute con valores para los parámetros proporcionados. No podemos ver qué valores se pasaron realmente al SQLExecute aunque podemos inferir de lo que vemos en Access. Solo puede saber si obtuvo una sola fila (usando SQLExecute: (GOTO BOOKMARK) o filas múltiples (usando SQLExecute: (MULTI-ROW FETCH) ). Access usará la versión de varias filas para realizar una búsqueda en segundo plano y llenar el conjunto de registros de forma incremental, pero usará la versión de una sola fila para llenar solo una fila. Ese podría ser el caso en una vista de formulario único en lugar de una vista de formulario continuo o de hoja de datos o usarlo para volver a sincronizar después de una actualización.

Navegar

Con un conjunto de registros lo suficientemente grande, es posible que Access no pueda terminar de recuperar todos los registros. Como se señaló anteriormente, al usuario se le presentan los datos lo antes posible. Normalmente, cuando el usuario navega hacia adelante a través del conjunto de registros, Access seguirá obteniendo más y más registros para mantener el búfer por delante del usuario.

Pero suponga que el usuario salta a la fila 100 yendo al control de navegación e ingresando 100 allí.

En ese caso, Access enviará las siguientes consultas...

SQLExecute: (MULTI-ROW FETCH)

SQLExecute: (GOTO BOOKMARK)

SQLExecute: (MULTI-ROW FETCH)

SQLExecute: (MULTI-ROW FETCH)
Observe cómo Access usa las declaraciones ya preparadas que creó en el momento de abrir el conjunto de registros. Debido a que ya tiene las claves de la primera consulta, puede saber cuál es la fila "100". Para usar un ejemplo más concreto. Supongamos que tuviéramos CityID comenzando en 1, 3, 4, 5…99, 100, 101, 102 sin registro para el CityID = 2 . En la primera consulta, el CityID 101 estaría en la fila 100. Por lo tanto, cuando el usuario salta a 100, Access busca la fila 100 en la primera consulta, ve que es CityID 101, luego toma ese valor y lo introduce en SQLExecute: (GOTO BOOKMARK) para navegar inmediatamente a ese registro. Luego mira los siguientes 10 registros y usa esos CityID subsiguientes para llenar el búfer con múltiples SQLExecute: (MULTI-ROW FETCH) . Es posible que haya notado que hay una búsqueda de varias filas antes de una búsqueda de una sola fila. Access en realidad obtiene las filas 101 a 110 en la búsqueda de filas múltiples y obtiene el registro número 100 en la siguiente búsqueda de una sola fila.

Una vez que Access ha obtenido los datos de las filas en la fila 100, lleva al usuario allí y comienza a llenar el búfer alrededor de esa fila 100. Eso permite al usuario ver la fila 100 sin tener que esperar para cargar todos los registros 11 a 99. El usuario también tiene una experiencia de navegación aparentemente rápida cuando hace clic en anterior o siguiente desde la nueva posición porque Access ya lo cargó en segundo plano antes de que el usuario lo solicitara. Eso ayuda a dar la ilusión de ser rápido incluso en una red lenta.

Pero incluso si el usuario dejaba el formulario abierto e inactivo, Access continuaría realizando la búsqueda en segundo plano y actualizando el búfer para evitar mostrar al usuario datos obsoletos. Eso se rige por la configuración de ODBC en el cuadro de diálogo Opciones, en la sección Avanzado en la pestaña Configuración del cliente:

El valor predeterminado para el intervalo de actualización de ODBC es de 1500 segundos, pero se puede cambiar. También se puede cambiar a través de VBA.

Conclusiones:Chunky o hablador

Ahora debería ver que la razón principal por la que los conjuntos de registros de tipo dynaset son actualizables pero los conjuntos de registros de tipo instantánea no lo son es porque Access puede sustituir una fila en el conjunto de registros con la versión más reciente del mismo desde el servidor, ya que sabe cómo seleccionar un unica fila. Por esa razón, Access necesita administrar 2 consultas ODBC; uno para obtener las claves y otro para obtener el contenido real de las filas para una clave determinada. Esa información no estaba presente con un conjunto de registros de tipo instantánea. Acabamos de obtener una gran cantidad de datos.

Analizamos 2 tipos principales de conjuntos de registros, aunque hay más. Sin embargo, otros son solo variantes de los 2 tipos que cubrimos. Pero por ahora, basta con recordar que usar instantáneas es ser pesado en nuestra comunicación de red. Por otro lado, usar dynaset significa que seremos conversadores. Ambos tienen sus altibajos.

Por ejemplo, el conjunto de registros de instantáneas no necesita más comunicación con el servidor una vez que ha recuperado los datos. Mientras el conjunto de registros permanezca abierto, Access puede navegar libremente por su caché local. El acceso tampoco necesita mantener ningún bloqueo y, por lo tanto, bloquear a otros usuarios. Sin embargo, un conjunto de registros de instantáneas es necesariamente más lento de abrir, ya que tiene que recopilar todos los datos por adelantado. Puede ser una mala opción para un gran conjunto de registros, incluso si tiene la intención de leer todos los datos.

Suponga que está creando un gran informe de Access de 100 páginas; por lo general, vale la pena usar un conjunto de registros de tipo dynaset. Puede comenzar a renderizar la vista previa tan pronto como tenga suficiente para renderizar la primera página. Eso es mejor que obligarlo a esperar hasta que haya recuperado todos los datos antes de que pueda comenzar a generar la vista previa. Aunque un conjunto de registros de Dynaset puede tomar bloqueos, por lo general es por un breve período de tiempo. Solo es suficiente para que Access vuelva a sincronizar su caché local.

Pero cuando pensamos en cuántas solicitudes más envía Access a través de la red con un conjunto de registros de tipo dynaset, es fácil ver que si la latencia de la red es baja, el rendimiento de Access se verá afectado en consecuencia. Para que Access permita a los usuarios editar y actualizar las fuentes de datos de manera genérica, es necesario que Access realice un seguimiento de las claves para seleccionar y modificar una sola fila. Veremos esto en los próximos artículos. En el próximo artículo, veremos cómo la clasificación y los grupos afectan un conjunto de registros de tipo dynaset y cómo Access determina la clave que se utilizará para un conjunto de registros de tipo dynaset.

Para obtener más ayuda con Microsoft Access, llame a nuestros expertos al 773-809-5456 o envíenos un correo electrónico a [email protected].