TN045. Поддержка MFC и баз данных для типов Long Varchar и Varbinary
Примечание.
Следующее техническое примечание не было обновлено, поскольку сначала оно было включено в электронную документацию. В результате некоторые процедуры и разделы могут быть устаревшими или неверными. Для получения последних сведений рекомендуется выполнить поиск интересующей темы в алфавитном указателе документации в Интернете.
В этом примечании описывается, как получить и отправить SQL_LONGVARCHAR ODBC и SQL_LONGVARBINARY типы данных с помощью классов баз данных MFC.
Обзор поддержки Long Varchar/Varbinary
OdBC SQL_LONG_VARCHAR и SQL_LONGBINARY типы данных (называемые здесь длинными столбцами данных) могут содержать огромные объемы данных. Существует 3 способа обработки этих данных:
Привязать его к объекту
CString
/CByteArray
.Привязать его к объекту
CLongBinary
.Не привязывайте его вообще и не извлекайте и отправляйте длинное значение данных вручную, независимо от классов базы данных.
Каждый из трех методов имеет преимущества и недостатки.
Длинные столбцы данных не поддерживаются для параметров запроса. Они поддерживаются только для outputColumns.
Привязка столбца длинных данных к CString/CByteArray
Преимущества.
Этот подход прост в понимании, и вы работаете с знакомыми классами. Платформа обеспечивает CFormView
поддержку CString
для DDX_Text
. У вас есть много общих функций строки или коллекции с CString
классами и CByteArray
вы можете контролировать объем памяти, выделенной локально для хранения значения данных. Платформа поддерживает старую копию данных поля во время Edit
или AddNew
вызовы функций, а платформа может автоматически обнаруживать изменения данных.
Примечание.
Так как CString
он предназначен для работы с символьным данными и CByteArray
для работы с двоичными данными, рекомендуется поместить символьные данные (SQL_LONGVARCHAR) CString
в , а двоичные данные (SQL_LONGVARBINARY) в CByteArray
.
Функции CString
RFX для и 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_VARCHAR или SQL_VARBINARY. Во время Edit
значения данных кэшируются, а затем сравниваются при Update
вызове, чтобы обнаружить изменения значения данных и задать значения "Грязный" и NULL для столбца соответствующим образом.
Привязка столбца длинных данных к CLongBinary
Если ваш длинный столбец данных может содержать больше байтов MAXINT данных, вероятно, следует рассмотреть возможность его извлечения в CLongBinary
.
Преимущества.
При этом извлекается весь длинный столбец данных до доступной памяти.
Недостатки.
Данные хранятся в памяти. Этот подход также является запретительно дорогостоящим для очень больших объемов данных. Чтобы убедиться, что поле включено в операцию, необходимо вызвать SetFieldDirty
связанный Update
элемент данных.
Если вы извлекаете длинные столбцы данных в CLongBinary
объект, классы базы данных будут проверка общий размер длинного столбца данных, а затем выделить HGLOBAL
сегмент памяти достаточно большой для хранения всего значения данных. Затем классы базы данных извлекают все значение данных в выделенный HGLOBAL
объект.
Если источник данных не может вернуть ожидаемый размер длинного столбца данных, платформа вызовет исключение AFX_SQL_ERROR_SQL_NO_TOTAL. Если попытка выделить сбой, создается исключение стандартной HGLOBAL
памяти.
ClassWizard привязывает SQL_LONGVARCHAR или SQL_LONGVARBINARY к CLongBinary
вам. Выберите CLongBinary
в качестве типа переменной в диалоговом окне "Добавить переменную члена". КлассWizard добавит вызов DoFieldExchange
и добавит RFX_LongBinary
общее количество привязанных полей.
Чтобы обновить длинные значения столбцов данных, сначала убедитесь, что выделенный HGLOBAL
размер достаточно велик для хранения новых данных путем вызова ::GlobalSize в элементе m_hData элемента CLongBinary
. Если он слишком мал, отпустите HGLOBAL
и выделите один соответствующий размер. Затем задайте m_dwDataLength , чтобы отразить новый размер.
В противном случае, если m_dwDataLength превышает размер заменяемых данных, можно освободить и перераспределить HGLOBAL
его или оставить выделенным. Обязательно укажите количество байтов, фактически используемых в m_dwDataLength.
Как выполняется обновление CLongBinary
Не обязательно понимать, как обновляется CLongBinary
работа, но это может быть полезно в качестве примера по отправке длинных значений данных в источник данных, если выбрать этот третий метод, описанный ниже.
Примечание.
Чтобы CLongBinary
поле было включено в обновление, необходимо явно вызвать SetFieldDirty
поле. Если изменить поле, в том числе задать значение NULL, необходимо вызвать SetFieldDirty
. Кроме того, необходимо вызвать SetFieldNull
второй параметр false, чтобы пометить поле как значение.
При обновлении CLongBinary
поля классы баз данных используют механизм DATA_AT_EXEC ODBC (см. документацию ODBC по SQLSetPos
аргументу rgbValue). Когда платформа подготавливает инструкцию insert или update вместо указания HGLOBAL
на содержащие данные, адрес CLongBinary
столбца задается в качестве значения столбца, а индикатор длины, заданный для SQL_DATA_AT_EXEC. Позже, когда инструкция обновления отправляется источнику данных, SQLExecDirect
возвращается SQL_NEED_DATA. Это оповещает платформу о том, что значение param для этого столбца фактически является адресом CLongBinary
. Платформа вызывает SQLGetData
один раз с небольшим буфером, ожидая, что драйвер возвращает фактическую длину данных. Если драйвер возвращает фактическую длину двоичного большого объекта (BLOB), MFC перераспределяет столько места, сколько необходимо для получения БОЛЬШОго двоичного объекта. Если источник данных возвращает SQL_NO_TOTAL, указывая, что он не может определить размер БОЛЬШОго двоичного объекта, MFC создаст меньшие блоки. Начальный размер по умолчанию составляет 64 КБ, а последующие блоки будут двойными. например, второй будет 128K, третий — 256K и т. д. Исходный размер можно настроить.
Не привязка: извлечение и отправка данных непосредственно из ODBC с помощью SQLGetData
С помощью этого метода можно полностью обойти классы базы данных и самостоятельно справиться с длинным столбцом данных.
Преимущества.
При необходимости можно кэшировать данные на диск или определять динамические объемы получаемых данных.
Недостатки.
Вы не получаете платформу Edit
или AddNew
поддержку, и вам необходимо самостоятельно написать код для выполнения основных функций (Delete
работает, хотя это не операция уровня столбца).
В этом случае длинный столбец данных должен находиться в списке выборок набора записей, но не должен быть привязан к платформе. Один из способов сделать это — предоставить собственную инструкцию SQL через GetDefaultSQL
или как аргумент lpszSQL функцииCRecordset
Open
, а не привязать дополнительный столбец к вызову функции RFX_. ДЛЯ ODBC требуется, чтобы несвязанные поля отображались справа от привязанных полей, поэтому добавьте в конец списка выбора несвязанный столбец или столбцы.
Примечание.
Так как длинный столбец данных не привязан к платформе, изменения в нем не будут обрабатываться с CRecordset::Update
помощью вызовов. Необходимо создать и отправить необходимые инструкции SQL INSERT и UPDATE самостоятельно.
См. также
Технические примечания по номеру
Технические примечания по категории