TN045. Поддержка MFC и баз данных для типов Long Varchar и Varbinary
Примечание
Следующее техническое примечание не было обновлено, поскольку сначала оно было включено в электронную документацию.В результате некоторые процедуры и разделы могут быть устаревшими или неверными.Для получения последних сведений рекомендуется выполнить поиск интересующей темы в алфавитном указателе документации в Интернете.
Эта заметка описывается извлечение и отправить типы данных ODBC SQL_LONGVARCHAR и SQL_LONGVARBINARY с помощью классов MFC базы данных.
Обзор длинных varchar/поддержки varbinary
Типы данных ODBC SQL_LONG_VARCHAR и SQL_LONGBINARY (в сосланные здесь как длинные столбцы данных) могут содержать большое количество данных. 3 Способа можно обрабатывать эти данные.
Привязать его к CString/CByteArray.
Привязать его к CLongBinary.
Привязка не выполняется, и не извлекать и не отправлять длинные значение данных вручную, не зависит от классов базы данных.
Каждый из методов 3 имеет свои преимущества и недостатки.
Длинные столбцы данных не поддерживаются для параметров в запрос. Они поддерживаются только для outputColumns.
Привязка длинный столбец в CString/CByteArray
Преимущества:
Этот подход прост для понимания, и работе с знакомыми классами. Платформа предоставляет поддержку CFormView для CString с DDX_Text. Имеется больших общей функции строки или коллекции с классами CString и CByteArray, а также элемент управления объем памяти выделяется локально для хранения данных значение. Платформа вызывает старой копии данных полей во время вызова функции Изменить или AddNew и платформа выполняет автоматическое обнаружение изменений к данным.
Примечание
Поскольку CString предназначен для работы в символьных данных и CByteArray для работы в двоичных данных, рекомендуется поместить символьные данные (SQL_LONGVARCHAR) в CString и двоичные данные (SQL_LONGVARBINARY) в CByteArray.
Функции RFX для CString и CByteArray имеют дополнительный аргумент, который позволяет переопределить размер по умолчанию выделения памяти для хранения возвращаемое значение столбца данных. Обратите внимание nMaxLength аргумент в следующих объявлениях функций:
void AFXAPI RFX_Text(CFieldExchange* pFX, const char *szName,
CString& value, int nMaxLength = 255, int nColumnType =
SQL_VARCHAR);
void AFXAPI RFX_Binary(CFieldExchange* pFX, const char *szName,
CByteArray& value,int nMaxLength = 255);
Если извлечь длинный столбец данных в CString или CByteArray, объем данных, возвращаемых максимумом, по умолчанию — 255 байт. Любые за этим игнорируется. В этом случае платформа создает исключение AFX_SQL_ERROR_DATA_TRUNCATED. Удачно, можно явно nMaxLength увеличения к большим значениям, до MAXINT.
Примечание
Значение nMaxLength MFC используется для задания локальный буфер функции SQLBindColumn.Это локальный буфер для хранилища данных и фактически не влияет на объем данных, возвращаемых драйвером ODBC.RFX_Text и RFX_Binary только один ее с помощью SQLFetch, чтобы получить данные из внутренней базы данных.Каждый драйвер ODBC имеет другое ограничение объема данных они могут возвращать в одной выборки.Это ограничение может быть меньшего, чем значение, установленое в nMaxLength; в этом случае которого создается исключение AFX_SQL_ERROR_DATA_TRUNCATED.В этих условиях, перейдите к использованию RFX_LongBinary вместо RFX_Text или RFX_Binary таким образом, чтобы все данные можно извлечь.
ClassWizard привязывает SQL_LONGVARCHAR в CString или SQL_LONGVARBINARY в CByteArray автоматически. Если необходимо выделить превышает 255 байт, необходимо извлечь его в длинн данные столбца, затем можно указывать значения для nMaxLength точными.
Когда длинный столбец привязан к CString или CByteArray, обновляемому работы на двух точно так же, как при его привязан к SQL_ SQL_VARCHAR или VARBINARY. Во время Изменить, задается значение кэшированного исчезает и сравнивается позже, когда вызывается метод Обновить для обнаружения изменений данных и задать значение пакостное и значения NULL для столбцов соответствующим образом.
Привязка длинный столбец в CLongBinary
Если длина данных столбца может содержать больше байтов данных MAXINT, необходимо рассмотреть может извлекать их в CLongBinary.
Преимущества:
Извлекает все это длинный столбец данных, до доступной памяти.
Недостатки:
Хранить данные в памяти. Этот подход также запретительно ресурсов для очень больших объемов данных. Необходимо вызвать SetFieldDirty для члена связанных данных, чтобы убедиться, что поле включается в операции Обновить.
Если извлечь длинные столбцы данных в CLongBinary, классы базы данных проверяют общий размер длинного столбца данных, затем выделяет сегмент памяти HGLOBAL достаточно велик для хранения всех его значение данных. Классы базы данных затем извлекает все данные в выбранное значение HGLOBAL.
Если источник данных не может возвращать ожидаемый размер длинного столбца данных, платформа создает исключение AFX_SQL_ERROR_SQL_NO_TOTAL. Если попытка выделения HGLOBAL завершается сбоем, это стандартное исключение возникает памяти.
ClassWizard привязывает SQL_LONGVARCHAR или SQL_LONGVARBINARY в CLongBinary автоматически. Выберите CLongBinary как тип переменной в диалоговом окне добавления переменной-члена. ClassWizard затем добавить вызов RFX_LongBinary в вызов DoFieldExchange и увеличивает общее количество ограниченных полей.
Обновление длинные значения столбца данных, сначала убедитесь, что выбранное HGLOBAL достаточно большое, чтобы хранить свои новые данные с помощью метода ::GlobalSize в элементе m_hDataCLongBinary. Если оно слишком мал, параметры HGLOBAL и выделите один соответствующий размер. Затем присвойте m_dwDataLength так, чтобы он отражал новый размер.
В противном случае если m_dwDataLength превышает размер данных можно заменить можно любой свободные и перераспределяете HGLOBAL, или оставьте его выбранный. Следует указать число байтов, используемое в m_dwDataLength.
Процесс обновления CLongBinary работает
Также необходимо понимать, как обновить CLongBinary работает, но может быть полезным в качестве примера, как отправлять длинные значения данных в источник данных, если выбран этот третий метод, описаны ниже.
Примечание
Для того, чтобы поле CLongBinary, в обновлении, необходимо явно вызывать SetFieldDirty для поля.При внесении любых изменений в поле, включая ее значение NULL, необходимо вызвать SetFieldDirty.Кроме того, необходимо вызвать SetFieldNull, выбрав второй параметр значение ЛОЖЬ, чтобы указать поле имеет значение.
При обновлении поле CLongBinary, механизм ODBC DATA_AT_EXEC использования классов базы данных (см. в документации по ODBC в аргументе rgbValue SQLSetPos ). Когда платформа подготавливает вставку или выписка обновления, а не указывал на HGLOBAL, содержащая данные, адресCLongBinary задается в качестве значения столбца вместо этого и индикатор длины, равным SQL_DATA_AT_EXEC. Позднее, когда выписка обновления будет передается источнику данных, функция SQLExecDirect возвращает значение SQL_NEED_DATA. Это предупреждает платформа param, что значение для этого столбца на самом деле адрес CLongBinary. Платформа вызывает функцию SQLGetData один раз с небольшой буфер, ожидая драйвер для возврата фактическая длина данных. Если драйвер возвращает фактическая длина большого двоичного объекта (БОЛЬШИХ ДВОИЧНОГО ОБЪЕКТА), MFC перераспределяет как можно больше места по мере необходимости для получения БОЛЬШОЙ ДВОИЧНЫЙ ОБЪЕКТ. Если источник данных возвращает значение SQL_NO_TOTAL, означающее, что он не может определить размер БОЛЬШИХ ДВОИЧНОГО ОБЪЕКТА, MFC создает более мелкие блоки. Первоначального размера по умолчанию размер и последующие блоки будут в два раза больший; например, будет 128K второй, третий 256K и т д Первоначального размера конфигурируется.
Привязка не: Нужно получить или отправя данных непосредственно из ODBC с SQLGetData
С помощью этого метода разработчик самостоятельно полностью обходите классы базы данных и о с длинным столбец данных.
Преимущества:
Можно кэшировать данные на диск при необходимости или даже динамически количество данных, которые необходимо извлечь.
Недостатки:
Не получать поддержку Изменить или AddNew платформы и самостоятельно необходимо написать код для выполнения базовую функциональность (Удалить работает тем не менее, поскольку нет операции над столбцами ровной).
В этом случае длина столбца данных должен находиться в списке select набора записей, но не должен быть привязан к структуре. Одним из способов является предоставить собственное инструкции SQL с помощью GetDefaultSQL или в качестве аргумента в функцию lpszSQL CRecordsetОткрыть, не привязки дополнительный столбец при вызове функции RFX_. ODBC требует, чтобы для поля отображаются справа от ограниченных полей, поэтому добавляет свои несвязанный столбец или столбцы в конец select списка.
Примечание
Поскольку в длинный столбец данных не привязан платформой, изменения в него не будут обрабатываться с вызовами CRecordset::Update.Необходимо создать самостоятельно и отправлять необходимое SQL выписки INSERT и UPDATE.