Conjunto de registros: Enlazar dinámicamente columnas de datos (ODBC)

Este tema es aplicable a las clases ODBC de MFC.

Los conjuntos de registros administran el enlace de las columnas de tabla que se especifican en tiempo de diseño, pero hay casos en los que es posible que quiera enlazar columnas que desconoce en tiempo de diseño. En este tema se explica:

Nota:

Este tema se aplica a objetos derivados de CRecordset donde no se haya implementado la obtención masiva de filas. Por lo general, si usa la obtención masiva de filas, las técnicas descritas no son recomendables. Para más información sobre la obtención masiva de filas, vea Conjunto de registros: obtener registros de forma masiva (ODBC).

Cuando puede enlazar columnas dinámicamente

Nota:

El Asistente para consumidores ODBC MFC no está disponible en Visual Studio 2019 ni en versiones posteriores. Aun así, puede crear un consumidor manualmente.

En tiempo de diseño, el Asistente para aplicaciones MFC o el Asistente para consumidores ODBC de MFC (desde Agregar clase) crea clases de conjunto de registros en función de las tablas y columnas conocidas del origen de datos. Las bases de datos pueden cambiar entre el momento de diseñarlas y cuando la aplicación usa esas tablas y columnas en tiempo de ejecución. Usted u otro usuario puede agregar o quitar una tabla o una columna de una tabla de la que depende el conjunto de registros de la aplicación. Puede que esto no sea un problema para todas las aplicaciones de acceso a datos, pero si se trata de la suya, ¿cómo puede afrontar los cambios en el esquema de base de datos sin tener que rediseñar y volver a compilar? El propósito de este tema es responder esa pregunta.

En este tema se describe el caso más común en el que podría enlazar las columnas de forma dinámica: cuando se ha empezado con un conjunto de registros basado en un esquema de base de datos conocido y se quiere trabajar con columnas adicionales en tiempo de ejecución. Además, en el tema se da por supuesto que las columnas adicionales se asignan a miembros de datos de campo CString, el caso más común, aunque se proporcionan sugerencias para ayudarle a administrar otros tipos de datos.

Con una pequeña cantidad de código adicional, puede hacer lo siguiente:

El conjunto de registros todavía contiene miembros de datos para las columnas que ya conocía en tiempo de diseño. También contiene una pequeña cantidad de código adicional que determina de forma dinámica si se han agregado columnas nuevas a la tabla de destino y, si es así, enlaza estas columnas nuevas a almacenamiento asignado de forma dinámica (en lugar de miembros de datos del conjunto de registros).

En este tema no se describen otros casos de enlace dinámico, como las tablas o columnas eliminadas. Para esos casos, tendrá que usar llamadas de API de ODBC más directamente. Para obtener información, consulte la Referencia del programador de ODBC.

Cómo enlazar columnas dinámicamente

Para enlazar columnas de forma dinámica, debe conocer (o poder determinar) los nombres de las columnas adicionales. También tendrá que asignar almacenamiento para los miembros de datos de campo adicionales, especificar sus nombres y sus tipos, y el número de columnas que se van a agregar.

En la descripción siguiente se mencionan dos conjuntos de registros diferentes. El primero es el conjunto de registros principal que selecciona los registros de la tabla de destino. El segundo es un conjunto de registros de columna especial que se usa para obtener información sobre las columnas de la tabla de destino.

Proceso general

En el nivel más general, siga estos pasos:

  1. Cree el objeto de conjunto de registros principal.

    Opcionalmente, pase un puntero a un objeto CDatabase abierto o tenga la capacidad de proporcionar información de conexión al conjunto de registros de columna de alguna otra manera.

  2. Siga los pasos para agregar columnas de forma dinámica.

    Vea el proceso que se describe en Adición de las columnas a continuación.

  3. Abra el conjunto de registros principal.

    El conjunto de registros selecciona los registros y usa el intercambio de campos de registros (RFX) para enlazar las columnas estáticas (las que se asignan a miembros de datos de campo del conjunto de registros) y las columnas dinámicas (las que se asignan al almacenamiento adicional que se asigna).

Agregar las columnas

El enlace dinámico de las columnas agregadas en tiempo de ejecución requiere los pasos siguientes:

  1. Determine en tiempo de ejecución qué columnas se encuentran en la tabla de destino. De esta información, se extrae una lista de las columnas que se han agregado a la tabla desde que se ha diseñado la clase del conjunto de registros.

    Un enfoque correcto consiste en usar una clase de conjunto de registros de columna diseñada para consultar el origen de datos para obtener información de columna para la tabla de destino (por ejemplo, el tipo de datos y el nombre de las columnas).

  2. Proporcione almacenamiento para los nuevos miembros de datos de campo. Como la clase del conjunto de registros principal no tiene miembros de datos de campo para las columnas desconocidas, debe proporcionar un lugar para almacenar los nombres, los valores de resultado y, posiblemente, información de tipo de datos (si las columnas son de tipos de datos diferentes).

    Un enfoque consiste en crear una o varias listas dinámicas: una para los nombres de las columnas nuevas, otra para los valores de resultado y una tercera para sus tipos de datos (si es necesario). Estas listas, en concreto la de valores, proporcionan la información y el almacenamiento necesarios para el enlace. En la figura siguiente se ilustra la creación de las listas.

    Building lists of columns to bind dynamically.
    Compilar listas de columnas para enlazarlas dinámicamente

  3. Agregue una llamada de función RFX a la función DoFieldExchange del conjunto de registros principal para cada columna agregada. Estas llamadas RFX se encargan de capturar un registro, incluir las columnas adicionales y enlazar las columnas a miembros de datos del conjunto de registros o al almacenamiento que se les haya asignado de forma dinámica.

    Un enfoque consiste en agregar un bucle a la función DoFieldExchange del conjunto de registros principal que recorra la lista de las columnas nuevas y llame a la función RFX correspondiente para cada columna de la lista. En cada llamada RFX, pase un nombre de columna de la lista de nombres de columna y una ubicación de almacenamiento en el miembro correspondiente de la lista de valores de resultado.

Listas de columnas

Las cuatro listas con las que tiene que trabajar se muestran en la tabla siguiente.

List Descripción
Columnas de la tabla actual (Lista 1 en la ilustración) Una lista de las columnas que están actualmente en la tabla del origen de datos. Es posible que esta lista coincida con la de columnas enlazadas actualmente en el conjunto de registros.
Columnas enlazadas del conjunto de registros (Lista 2 en la ilustración) Una lista de las columnas enlazadas en el conjunto de registros. Estas columnas ya contienen instrucciones RFX en la función DoFieldExchange.
Columnas para enlazar de forma dinámica (Lista 3 en la ilustración) Una lista de las columnas que están en la tabla pero no en el conjunto de registros. Son las columnas que quiere enlazar de forma dinámica.
Valores de las columnas dinámicas (Lista 4 en la ilustración) Una lista que contiene almacenamiento para los valores recuperados de las columnas que se enlazan de forma dinámica. Los elementos de esta lista se corresponden, uno a uno, con los de Columnas para enlazar de forma dinámica.

Creación de listas

Con una estrategia general en mente, puede pasar a los detalles. En los procedimientos descritos en el resto de este tema se muestra cómo generar las listas mostradas en Listas de columnas. Los procedimientos sirven de guía para que pueda:

Determinar qué columnas de tabla no están en el conjunto de registros

Cree una lista (Columnas enlazadas del conjunto de registros, como en la Lista 2 de la ilustración) que contenga una lista de las columnas ya enlazadas en el conjunto de registros principal. Después, cree una lista (Columnas para enlazar de forma dinámica, derivada de Columnas de la tabla actual y Columnas enlazadas del conjunto de registros) que contenga los nombres de columna que están en la tabla del origen de datos, pero no en el conjunto de registros principal.

Para determinar los nombres de las columnas que no están en el conjunto de registros (Columnas para enlazar de forma dinámica)
  1. Cree una lista (Columnas enlazadas del conjunto de registros) de las columnas ya enlazadas en el conjunto de registros principal.

    Un enfoque consiste en crear Columnas enlazadas del conjunto de registros en tiempo de diseño. Para obtener estos nombres, puede examinar de forma visual las llamadas de función RFX en la función DoFieldExchange del conjunto de registros. Después, establezca la lista como una matriz inicializada con los nombres.

    Por ejemplo, en la ilustración se muestra Columnas enlazadas del conjunto de registros (Lista 2) con tres elementos. En Columnas enlazadas del conjunto de registros falta la columna Phone que se muestra en Columnas de la tabla actual (Lista 1).

  2. Compare Columnas de la tabla actual y Columnas enlazadas del conjunto de registros para crear una lista (Columnas para enlazar de forma dinámica) de las columnas que todavía no están enlazadas en el conjunto de registros principal.

    Un enfoque consiste en recorrer en bucle la lista de columnas de la tabla en tiempo de ejecución (Columnas de la tabla actual) y la de columnas ya enlazadas en el conjunto de registros (Columnas enlazadas del conjunto de registros) en paralelo. En Columnas para enlazar de forma dinámica, incluya todos los nombres de Columnas de la tabla actual que no aparezcan en Columnas enlazadas del conjunto de registros.

    Por ejemplo, en la ilustración se muestra Columnas para enlazar de forma dinámica (Lista 3) con un elemento: la columna Phone encontrada en Columnas de la tabla actual (Lista 1) pero no en Columnas enlazadas del conjunto de registros (Lista 2).

  3. Cree una lista Valores de las columnas dinámicas (como en la Lista 4 de la ilustración) para almacenar los valores de datos correspondientes a cada nombre de columna almacenado en la lista de columnas que se van a enlazar de forma dinámica (Columnas para enlazar de forma dinámica).

    Los elementos de esta lista desempeñan el rol de miembros de datos de campo nuevos del conjunto de registros. Son las ubicaciones de almacenamiento a las que se enlazan las columnas dinámicas. Para obtener descripciones de las listas, vea Listas de columnas.

Proporcionar almacenamiento para las nuevas columnas

A continuación, defina ubicaciones de almacenamiento para las columnas que se van a enlazar de forma dinámica. La idea es proporcionar un elemento de lista en el que almacenar el valor de cada columna. Estas ubicaciones de almacenamiento son similares a las variables miembro del conjunto de registros, que almacenan las columnas enlazadas con normalidad.

Para proporcionar almacenamiento dinámico para las columnas nuevas (Valores de las columnas dinámicas)

  1. Cree Valores de las columnas dinámicas, en paralelo a Columnas para enlazar de forma dinámica, para contener el valor de los datos de cada columna.

    Por ejemplo, en la ilustración se muestra Valores de las columnas dinámicas (Lista 4) con un elemento: un objeto CString que contiene el número de teléfono real para el registro actual: “555-1212”.

    En el caso más común, Valores de las columnas dinámicas tiene elementos de tipo CString. Si trabaja con columnas de diferentes tipos de datos, necesita una lista que pueda contener elementos de varios tipos.

El resultado de los procedimientos anteriores son dos listas principales: Columnas para enlazar de forma dinámica contiene los nombres de las columnas y Valores de las columnas dinámicas contiene los valores de las columnas para el registro actual.

Sugerencia

Si las columnas nuevas no son todas del mismo tipo de datos, es posible que quiera una lista paralela adicional que contenga elementos que definan de algún modo el tipo de cada elemento correspondiente en la lista de columnas. (Puede usar los valores AFX_RFX_BOOL, AFX_RFX_BYTE, etc., para ello si lo desea. Estas constantes se definen en AFXDB.H.) Elija un tipo de lista en función de cómo represente los tipos de datos de columna.

Agregar llamadas RFX para enlazar las columnas

Por último, para preparar el enlace dinámico, coloque llamadas RFX para las nuevas columnas en la función DoFieldExchange.

Para agregar llamadas RFX de forma dinámica para las columnas nuevas
  1. En la función miembro DoFieldExchange del conjunto de registros principal, agregue código que recorra en bucle la lista de columnas nuevas (Columnas para enlazar de forma dinámica). En cada bucle, extraiga un nombre de columna desde Columnas para enlazar de forma dinámica y un valor de resultado para la columna desde Valores de las columnas dinámicas. Pase estos elementos a una llamada de función RFX adecuada para el tipo de datos de la columna. Para obtener descripciones de las listas, vea Listas de columnas.

En el caso habitual, en las llamadas de función RFX_Text se extraen objetos CString de las listas, como se muestra en las líneas de código siguientes, donde Columnas para enlazar de forma dinámica es un elemento CStringList denominado m_listName y Valores de las columnas dinámicas es un elemento CStringList denominado m_listValue:

RFX_Text( pFX,
            m_listName.GetNext( posName ),
            m_listValue.GetNext( posValue ));

Para más información sobre las funciones RFX, vea Macros y variables globales en la Referencia de la biblioteca de clases.

Sugerencia

Si las columnas nuevas son de tipos de datos distintos, use una instrucción switch en el bucle para llamar a la función RFX adecuada para cada tipo.

Cuando el marco de trabajo llama a DoFieldExchange durante el proceso Open para enlazar las columnas al conjunto de registros, las llamadas RFX para las columnas estáticas enlazan esas columnas. Después, el bucle llama repetidamente a las funciones RFX para las columnas dinámicas.

Consulte también

Conjunto de registros (ODBC)
Conjunto de registros: Trabajar con grandes elementos de datos (ODBC)