Набор записей. Динамическая привязка столбцов данных (ODBC)

Этот раздел относится к классам ODBC библиотеки MFC.

Наборы записей управляют привязкой столбцов таблицы, заданной во время разработки. Однако иногда может требоваться привязать столбцы, которые не были известны во время разработки. В этом разделе рассматриваются следующие вопросы.

Примечание.

Этот раздел относится к объектам, производным от CRecordset, в которых пакетное получение строк не реализовано. Если вы используете пакетное получение строк, применять описанные в ней методы, как правило, не рекомендуется. Дополнительные сведения о выборке массовых строк см. в разделе Recordseting Records: Получение записей в пакетной службе (ODBC).

При динамической привязке столбцов

Примечание.

Мастер потребителя MFC ODBC недоступен в Visual Studio 2019 и более поздних версиях. При этом вы по-прежнему можете создать потребитель вручную.

Во время разработки мастер приложения MFC или мастер объекта-получателя ODBC MFC (доступен в диалоговом окне Добавление класса) создает классы наборов записей на основе известных таблиц и столбцов в источнике данных. Со времени разработки баз данных до момента их использования во время выполнения приложения их таблицы и столбцы могут меняться. Кто-либо из пользователей может добавить или удалить таблицу либо столбцы в таблице, с которой связан набор записей приложения. Такое случается не со всеми приложениями, обращающимися к данным, но если все же эта проблема возникла, то как решить ее, не прибегая к реструктуризации и повторной компиляции? Цель этой статьи — дать ответ на этот вопрос.

В этой статье описывается наиболее распространенный сценарий, в котором требуется использовать динамическую привязку столбцов: вы начинаете с набора записей на основе известной схемы базы данных, но во время выполнения появляются дополнительные столбцы. В статье предполагается, что дополнительные столбцы сопоставлены с элементами данных в полях типа CString (наиболее распространенный случай), однако приводятся рекомендации в отношении и других типов данных.

Добавив немного кода, вы можете:

Ваш набор записей по-прежнему содержит элементы данных для столбцов, которые были известны во время разработки. Он также содержит небольшой объем дополнительного кода, который динамически определяет, были ли добавлены новые столбцы в целевую таблицу, и, если да, привязывает эти новые столбцы к динамически выделяемому хранилищу (а не к элементам данных в наборе записей).

Другие сценарии динамической привязки, такие как удаление таблиц или столбцов, в этой статье не рассматриваются. В таких случаях необходимо использовать вызовы API ODBC более непосредственным образом. Дополнительные сведения см. в справочнике программиста ODBC.

Динамическое связывание столбцов

Для динамической привязки столбцов необходимо знать (или иметь возможность определить) имена дополнительных столбцов. Кроме того, необходимо выделить хранилище для дополнительных элементов данных полей, задать их имена и типы, а также указать количество добавляемых столбцов.

Далее будут упоминаться два разных набора записей. Первый — это главный набор записей, который выбирает записи из целевой таблицы. Второй — это специальный набор записей столбцов, который служит для получения сведений о столбцах в целевой таблице.

Общий процесс

В самом общем виде процедура выглядит так.

  1. Вы создаете объект главного набора записей.

    При необходимости можно передать указатель на открытый объект CDatabase или предоставить сведения о подключении в наборе записей столбцов каким-либо иным образом.

  2. Столбцы добавляются динамически.

    См. раздел "Добавление столбцов" ниже.

  3. Вы открываете главный набор записей.

    Набор записей выбирает записи и использует механизм обмена полями записей (RFX) для привязки как статических столбцов (сопоставленных с элементами данных полей в наборе записей), так и динамических столбцов (сопоставленных с дополнительным выделенным хранилищем).

Добавление столбцов

Для динамической привязки добавленных столбцов во время выполнения необходимо выполнить указанные ниже действия.

  1. Определите столбцы, имеющиеся в целевой таблице, во время выполнения. Извлеките из этих сведений список столбцов, которые были добавлены в таблицу с того момента, как был создан класс набора записей.

    Рекомендуется использовать класс набора записей столбцов, который запрашивает сведения о столбцах в целевой таблице (например, их имена и типы данных) из источника данных.

  2. Предоставьте хранилище для новых элементов данных полей. Так как в классе главного набора записей нет элементов данных полей для неизвестных столбцов, необходимо предоставить место для хранения имен, итоговых значений и, возможно, сведений о типах данных (если столбцы имеют разные типы данных).

    Один из способов — создать один или несколько динамических списков: один для имен новых столбцов, другой для итоговых значений, а третий для типов данных (если необходимо). Эти списки, особенно список значений, предоставляют сведения и место для хранения, которые требуются для привязки. Построение списков показано на рисунке ниже.

    Building lists of columns to bind dynamically.
    Построение списков столбцов для динамической привязки

  3. Для каждого добавленного столбца добавьте вызов функции RFX в функции DoFieldExchange главного набора записей. Эти вызовы RFX выполняют всю работу по получению записи, включая дополнительные столбцы, и привязке столбцов к элементам данных набора записей или динамически выделяемому хранилищу.

    Один из подходов — добавить в функцию DoFieldExchange главного набора записей цикл, который перебирает новые столбцы и вызывает для каждого из них соответствующую функцию RFX. При каждом вызове RFX необходимо передавать имя столбца из списка имен столбцов и место хранения в соответствующем элементе списка итоговых значений.

Списки столбцов

В таблице ниже представлены четыре списка, которые вам потребуются.

Список (List) Description
Текущие столбцы таблицы (Список 1 на рисунке.) Список столбцов, которые имеются в настоящее время в таблице в источнике данных. Может совпадать со списком текущих привязанных столбцов в наборе записей.
Привязанные столбцы набора записей (Список 2 на рисунке.) Список привязанных столбцов в наборе записей. Эти столбцы уже имеют инструкции RFX в функции DoFieldExchange.
Столбцы для динамической привязки (Список 3 на рисунке.) Список столбцов, имеющихся в таблице, но отсутствующих в наборе записей. Это столбцы, которые необходимо привязать динамически.
Значения из динамических столбцов (Список 4 на рисунке.) Список мест хранения значений, извлеченных из столбцов, которые привязываются динамически. Элементы этого списка соответствуют элементам в списке столбцов для динамической привязки в отношении "один к одному".

Создание списков

Получив общее представление, можно переходить к деталям. Далее в этой статье описываются процедуры создания списков, представленных в разделе Списки столбцов. Приводятся инструкции по выполнению следующих задач.

Определение столбцов таблицы, не входящих в набор записей

Создайте список столбцов, которые уже привязаны в главном наборе записей ("Привязанные столбцы набора записей", список 2 на рисунке). Затем создайте список ("Столбцы для динамической привязки", производный от "Текущие столбцы таблицы" и "Привязанные столбцы набора записей"), который содержит имена столбцов, имеющихся в таблице в источнике данных, но отсутствующих в главном наборе записей.

Определение имен столбцов, отсутствующих в наборе записей ("Столбцы для динамической привязки")
  1. Создайте список столбцов, которые уже привязаны в главном наборе записей ("Привязанные столбцы набора записей").

    Один из подходов — создание этого списка во время разработки. Чтобы получить имена столбцов, можно просмотреть вызовы функций RFX в функции DoFieldExchange набора записей. Затем создайте список как массив, инициализированный с использованием имен.

    Например, на рисунке показан список "Привязанные столбцы набора записей" (список 2) с тремя элементами. В списке "Привязанные столбцы набора записей" отсутствует столбец Phone, имеющийся в списке "Текущие столбцы таблицы" (список 1).

  2. Сравните списки "Текущие столбцы таблицы" и "Привязанные столбцы набора записей", чтобы сформировать список столбцов, которые еще не привязаны в главном наборе записей ("Столбцы для динамической привязки").

    Один из подходов — выполнить параллельный перебор списка столбцов в таблице ("Текущие столбцы таблицы") и списка столбцов, уже привязанных в наборе записей ("Привязанные столбцы набора записей"), во время выполнения. Поместите в список "Столбцы для динамической привязки" имена из списка "Текущие столбцы таблицы", которых нет в списке "Привязанные столбцы набора записей".

    Например, на рисунке показан список "Столбцы для динамической привязки" (список 3) с одним элементом — столбцом Phone, который есть в списке "Текущие столбцы таблицы" (список 1), но которого нет в списке "Привязанные столбцы набора записей" (список 2).

  3. Создайте список "Значения из динамических столбцов" (список 4 на рисунке), в котором будут храниться значения, соответствующие каждому имени столбца в списке "Столбцы для динамической привязки".

    Элементы этого списка выступают в качестве новых элементов данных полей в наборе записей. Они представляют собой места хранения, к которым привязаны динамические столбцы. Описание списков см. в разделе Списки столбцов.

Предоставление служба хранилища для новых столбцов

Далее настройте места для хранения столбцов, которые будут привязываться динамически. Для этого нужно предоставить элемент списка, в котором будет храниться значение столбца. Эти места хранения соответствуют переменным-членам набора записей, в которых хранятся статически привязанные столбцы.

Динамическое выделение хранилища для новых столбцов ("Значения из динамических столбцов")

  1. Вместе со списком "Столбцы для динамической привязки" создайте список "Значения из динамических столбцов", в котором будут содержаться значения из каждого столбца.

    Например, на рисунке показаны динамические значения столбцов (список 4) с одним элементом CString : объект, содержащий фактический номер телефона для текущей записи: "555-1212".

    Чаще всего список "Значения из динамических столбцов" содержит элементы типа CString. Если вы работаете со столбцами разных типов, нужен список, который может содержать элементы различных типов.

Результатом предыдущих процедур является два основных списка: столбцы к привязке динамически, содержащие имена столбцов и динамические значения столбцов, содержащие значения в столбцах текущей записи.

Совет

Если новые столбцы имеют разные типы данных, может потребоваться дополнительный список, каждый элемент которого определяет тип соответствующего элемента в списке столбцов. (Для этого можно использовать значения AFX_RFX_BOOL, AFX_RFX_BYTE и т. д. Эти константы определены в AFXDB.H.) Выберите тип списка на основе представления типов данных столбцов.

Добавление вызовов RFX для привязки столбцов

Наконец, организуйте динамическую привязку, добавив вызовы RFX для новых столбцов в функцию DoFieldExchange.

Динамическое добавление вызовов RFX для новых столбцов
  1. В функции-члене DoFieldExchange главного набора записей добавьте код, который перебирает список новых столбцов ("Столбцы для динамической привязки"). В каждом цикле должны извлекаться имя столбца из списка "Столбцы для динамической привязки" и итоговое значение для столбца из списка "Значения из динамических столбцов". Передайте эти элементы в вызов функции RFX, соответствующий типу данных столбца. Описание списков см. в разделе Списки столбцов.

В общем случае в вызовах функции RFX_Text из списков извлекаются объекты CString, как в следующих строках кода, где список "Столбцы для динамической привязки" — это CStringList с именем m_listName, а список "Значения из динамических столбцов" — CStringList с именем m_listValue:

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

Дополнительные сведения о функциях RFX см. в разделе Макросы и глобальные объекты в справочнике по библиотеке классов.

Совет

Если новые столбцы имеют разные типы данных, используйте в цикле оператор switch для вызова соответствующей функции RFX для каждого типа.

Когда платформа вызывает DoFieldExchange во время процесса Open с целью привязки столбцов к набору записей, вызовы RFX привязывают статические столбцы. Затем цикл вызывает функции RFX для динамических столбцов.

См. также

Набор записей (ODBC)
Набор записей. Работа с большими элементами данных (ODBC)