Набор записей. Динамическая привязка столбцов данных (ODBC)
Данный раздел относится к классам ODBC библиотеки MFC.
Наборы записей управляют привязкой столбцов таблицы, указанных во время разработки, но в некоторых случаях необходимо привязать столбцы, неизвестные во время разработки. Содержание раздела:
Ситуации, в которых требуется динамическая привязка столбцов к набору записей.
Динамическая привязка столбцов во время выполнения
Примечание
В этом разделе приведены сведения, относящиеся к объектам, производным от класса CRecordset, в котором групповая выборка строк не реализована.Не рекомендуется применять способы, описанные в этом разделе, если используется массовая выборка строк.Дополнительные сведения о групповой выборке строк см. в разделе Набор записей. Групповая выборка строк (ODBC).
Ситуации, в которых требуется динамическая привязка столбцов
Во время разработки мастер приложений MFC или мастер потребителя MFC ODBC (с помощью команды Добавить класс) создают классы набора записей на основе известных таблиц и столбцов в источнике данных. Базы данных могут изменяться с момента их разработки и после того, как приложение использует эти таблицы и столбцы во время выполнения. Пользователи могут добавить или удалить таблицу или столбцы в таблице, которую использует набор записей приложения. Возможно, это не является проблемой для приложений, осуществляющих доступ к данным, но если это приложение пользователя, то он сможет обработать изменения схемы базы данных только с помощью повторной разработки и перекомпиляции приложения. Предназначение этого раздела — предложить другой способ добавления и удаления столбцов.
В этом разделе описываются самый общий случай, в котором требуется динамическая привязка столбцов, начиная с набора записей на основе известной схемы базы данных, в которой необходимо динамически обработать дополнительные столбцы во время выполнения. Далее предполагается, что эти дополнительные столбцы сопоставляются с полями элементов данных класса CString в самом общем случае, но при этом предлагаются способы для обработки других типов данных.
Небольшой дополнительный код может:
помочь определить, какие столбцы доступны во время выполнения;
динамически привязать дополнительные столбцы к набору записей во время выполнения.
Набор записей все еще содержит элементы данных для столбцов, известных во время разработки. Он также содержит небольшой дополнительный код, который динамически определяет, добавлены ли новые столбцы в целевую таблицу, и привязывает их к динамически выделенному хранилищу (отличному от элементов данных набора записей).
В этом разделе не описаны другие случаи динамической привязки, такие как удаление таблиц или столбцов. В этих случаях необходимо непосредственно использовать вызовы API ODBC. Дополнительные сведения см. в Справочнике программиста пакета ODBC SDK на компакт-диске библиотеки MSDN.
Динамическая привязка столбцов
Для динамической привязки столбцов необходимо узнать (или иметь способ определить) имена дополнительных столбцов. Также необходимо выделить хранилище для дополнительных полей элементов данных, указать их имена и типы, а также задать количество добавляемых столбцов.
Ниже упоминаются два различных набора записей. Первый — основной набор записей, который выбирает записи из целевой таблицы. Второй — это специальный набор записей столбцов для получения сведений о столбцах в целевой таблице.
Общий процесс
В самом общем случае необходимо выполнить следующие действия.
Создать основной объект набора записей.
При необходимости передайте указатель открытому объекту CDatabase или предоставьте другой способ для передачи сведений о подключении набору записей столбцов.
Выполните действия для динамической привязки столбцов.
См. процесс, описанный ниже, в подразделе "Добавление столбцов".
Откройте основной объект набора записей.
Набор записей выбирает записи и использует обмен полей записи (RFX) для привязки как статических столбцов (сопоставленных с элементами данных полей набора записи), так и динамических столбцов (сопоставленных с дополнительным выделенным хранилищем).
Добавление столбцов
Для динамической привязки добавленных столбцов во время выполнения необходимо выполнить следующие действия.
Определить во время выполнения, какие столбцы расположены в целевой таблице. Получить список столбцов, добавленных в таблицу после первоначальной разработки набора записей.
Рекомендуется использовать класс столбцов набора записей для запроса у источника данных сведений о целевой таблице (например, имен столбцов и типов данных).
Предоставить хранилище для новых элементов данных полей. Так как в классе основного набора записей нет элементов данных полей для неизвестных столбцов, необходимо предоставить память для хранения имен, значений и, по возможности, сведений о типе данных (если используются столбцы разных типов).
Один из способов — построить один или несколько динамических списков, один — для имен новых столбцов, другой — для результирующих значений и третий — для их типов данных (при необходимости). Эти списки, в частности список значений, предоставляют сведения и хранилище для привязки. На следующем рисунке показано построение списков.
Построение списков столбцов для динамической привязки
Добавьте вызов функции RFX в основную функцию DoFieldExchange набора записей для каждого добавленного столбца. Эти вызовы выполняют работу по выборке записи, включая дополнительные столбцы, а также привязку столбцов к элементам данных набора записей или к динамическому хранилищу.
Один из способов — добавить в основную функцию DoFieldExchange набора записей цикл, выполняющий перебор списка новых столбцов и вызывающий соответствующую функцию RFX для каждого столбца в списке. При каждом вызове RFX следует передавать имя столбца из списка имен столбцов и расположение хранилища в соответствующем члене списка результирующих значений.
Списки столбцов
В следующей таблице показаны четыре списка, с которыми следует работать.
Столбцы текущей таблицы (список 1 на рисунке)
Список текущих столбцов в таблице в источнике данных. Этот список совпадает со списком столбов, привязанных к набору записей в текущий момент.Столбцы, привязанные к набору записей (список 2 на рисунке)
Список столбов, привязанных к набору записей. Для этих столбцов уже существуют операторы RFX в функции DoFieldExchange.Столбцы, которые необходимо динамически привязать (список 3 на рисунке)
Список столбов в таблице, которые отсутствуют в наборе записей. Эти столбцы необходимо динамически привязать к набору записей.Значения динамических столбцов (список 4 на рисунке)
Список, содержащий значения динамически привязанных столбцов. Элементы этого списка соответствуют элементам в списке столбцов, которые необходимо динамически привязать.
Построение списков
Теперь, когда известна общая стратегия, можно изучить детали. Процедуры, описанные далее в этом разделе, показывают, как построить списки показанные на рисунке Списки столбцов. В этих процедурах происходят следующие процессы.
Определение имен столбцов, отсутствующих в наборе записей.
Предоставление динамического хранилища для новых добавленных столбцов.
Динамическое добавление вызовов RFX для новых столбцов.
Определение столбцов, отсутствующих в наборе записей
Постройте список (столбцы, привязанные к набору записей, список 2 на рисунке), содержащий список столбцов, которые уже привязаны к основному набору записей. Затем постройте список (список столбцов, которые необходимо динамически привязать, производный от списка текущих столбцов в таблице и списка столбцов, привязанных к набору записей), содержащий имена столбцов, расположенных в таблице в источнике данных, но отсутствующих в основном наборе записей.
Определение имен столбцов, отсутствующих в наборе записей (список столбцов, которые необходимо динамически привязать)
Постройте список столбцов, уже привязанных к набору записей.
Один из способов сделать это — создать список столбцов, привязанных к набору записей, во время разработки. Для этого можно визуально изучить вызовы функций RFX в функции DoFieldExchange набора записей. Затем настройте список как массив, инициализируемый именами.
Например, на рисунке показан список столбцов, привязанных к набору записей (список 2), с тремя элементами. В списке столбцов, привязанных к набору записей, нет столбца "Phone", показанного в списке текущих столбцов в таблице (список 1).
Сравните список текущих столбцов в таблице и список столбцов, привязанных к набору записей, чтобы построить список столбцов, которые необходимо динамически привязать.
Один из способов сделать это — параллельно в цикле пройти по списку текущих столбцов в таблице во время выполнения и списку столбцов, уже привязанных к набору записей. В список столбцов, которые необходимо динамически привязать, добавьте имена столбцов из списка 1, которые отсутствуют в списке 2.
Например, на рисунке показан список 3 с одним элементом: столбец "Phone", обнаруженный в списке 1, но отсутствующий в списке 2.
Постройте список значений динамических столбцов (список 4 на рисунке), в котором хранятся значения данных, соответствующие каждому столбцу, чьи имена хранятся в списке столбцов, которые необходимо динамически привязать.
Элементы этого списка играют роль элементов данных полей нового набора записей. Это области памяти, к которым привязываются динамические столбцы. Описание списков см. в разделе Списки столбцов.
Предоставление хранилища для новых столбцов
Затем настройте области хранилища, к которым динамически привязываются новые столбцы. Идея заключается в том, чтобы предоставить элемент списка, в котором можно хранить значение каждого столбца. Эти области хранилища существуют параллельно переменным членов набора записей, в котором хранятся обычные привязанные столбцы.
Предоставление динамического хранилища для новых столбцов (список значений динамических столбцов)
Постройте список значений динамических столбцов параллельно со списком столбцов, которые необходимо привязать динамически, чтобы сохранить значение каждого столбца.
Например, на рисунке показан список 4 с одним элементом: объектом CString, содержащем фактический номер телефона для текущей записи ("555-1212").
В самом общем случае в списке значений динамических столбцов содержатся элементы типа CString. При использовании столбцов различных типов данных требуется список, способный хранить элементы разных типов данных.
Результатом описанной выше процедуры являются два списка: список столбцов, которые необходимо динамически привязать, содержащий имена столбцов и список значений динамических столбцов, содержащий значения столбцов текущей записи.
Совет
Если новые столбцы принадлежат разным типам данных, можно создать дополнительный параллельный список, содержащий элементы, определяющие тип каждого элемента в списке столбцов. (Можно использовать значенияAFX_RFX_BOOL, AFX_RFX_BYTE, и так далее.Эти константы определены в файле AFXDB.H). Выберите тип списка на основе представления типов данных столбцов.
Добавление вызовов функций RFX для привязки столбцов
Наконец, выполните действия для динамической привязки, а именно, разместите вызовы функций RFX для новых столбцов в функции DoFieldExchange.
Динамическое добавление вызовов функций RFX для новых столбцов
- В функции-члене 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 во время процесса открытия для привязки столбцов к набору записей, вызовы функций RFX для статических столбцов привязывают эти столбцы. Затем функции RFX вызываются в цикле для динамических столбцов.