TN045: Soporte para largo Varchar/Varbinary MFC/bases

Esta nota describe cómo recuperar y enviar los tipos de datos ODBC SQL_LONGVARCHAR y SQL_LONGVARBINARY utilizando las clases de base de datos MFC.

Descripción de largo Varchar/Varbinary apoyo

Los tipos de datos ODBC SQL_LONG_VARCHAR y SQL_LONGBINARY (denominados aquí largas columnas de datos) pueden contener grandes cantidades de datos. Hay tres maneras puede manejar estos datos:

Columnas de datos largos no son compatibles para los parámetros de una consulta. Sólo se admiten para outputColumns.

Una larga columna de datos de enlace para un CString/CByteArray

Ventajas:

Este enfoque es sencillo de entender y trabajar con clases familiares. El framework proporciona compatibilidad de CFormView de CString con DDX_Text. Dispones de cadena general o funcionalidad de colección con las clases de CByteArray y CString y puede controlar la cantidad de memoria asignada localmente que contenga el valor de datos. El marco mantiene una vieja copia de datos de campo durante la Edición o llamadas de función de AddNew y el marco puede detectar automáticamente los cambios en los datos por usted.

&Notanbsp;  Desde CString está diseñado para trabajar con datos de caracteres y CByteArray para trabajar en datos binarios, se recomienda poner los datos de carácter (SQL_LONGVARCHAR) en CStringy los datos binarios (SQL_LONGVARBINARY) en CByteArray.

Las funciones RFX CString y CByteArray tienen un argumento adicional que permite anular el tamaño predeterminado de memoria asignada para celebrar el valor recuperado de la columna de datos. Tenga en cuenta el argumento de nMaxLength en las siguientes declaraciones de función:

 void AFXAPI RFX_Text(CFieldExchange* pFX, const char *szName,
 nbsp;  CString & valor, int nMaxLength = 255, int nColumnType =
    SQL_VARCHAR);

void AFXAPI RFX_Binary(CFieldExchange* pFX, const char *szName, CByteArray& value,int nMaxLength = 255)

Si recupera una columna de datos long en un CString o CByteArray, máximo devuelto cantidad de datos es, por defecto, 255 bytes. Nada más allá de esto es ignorado. En este caso, el marco producirá la excepción AFX_SQL_ERROR_DATA_TRUNCATED. Afortunadamente, puede aumentar explícitamente nMaxLength a mayores valores, hasta MAXINT.

ClassWizard enlazará un SQL_LONGVARCHAR a un CStringo un SQL_LONGVARBINARY a un CByteArray para usted. Si desea asignar más de 255 bytes en que recuperará su columna de datos long, entonces puede proporcionar un valor explícito para nMaxLength.

Cuando una columna de datos long está enlazada a un CString o CByteArray, actualizar el campo funciona al igual que cuando está enlazado a un SQL_VARCHAR o SQL_VARBINARY. Durante la Edición, el valor de los datos en caché lejos y posteriormente en comparación cuando se llama a Update para detectar cambios en el valor de los datos y definir adecuadamente los valores sucio y Null para la columna.

Una larga columna de datos de enlace para un CLongBinary

Si la columna de datos largos puede contener más MAXINT bytes de datos, probablemente debería considerar recuperar en un CLongBinary.

Ventajas:

Se recupera de una columna de datos long todo - hasta la memoria disponible.

Desventajas:

Los datos se mantienen en la memoria. Este enfoque también es prohibitivo para cantidades muy grandes de datos. Se debe llamar a SetFieldDirty para el miembro de datos enlazados asegurar que el campo está incluido en una operación de actualización.

Si recupera columnas de datos long en un CLongBinary, las clases de base de datos Compruebe el tamaño total de la columna de datos long y asignar un segmento de memoria HGLOBAL suficientemente grande como para que se mantenga el valor de todos los datos. Las clases de base de datos, a continuación, recuperar el valor de datos completa en el asignado HGLOBAL.

Si el origen de datos no puede devolver el tamaño esperado de la columna de datos long, el marco producirá la excepción AFX_SQL_ERROR_SQL_NO_TOTAL. Si falla el intento de asignar el HGLOBAL , se produce una excepción de memoria estándar.

ClassWizard enlazará un SQL_LONGVARCHAR o SQL_LONGVARBINARY a un CLongBinary para usted. Seleccione CLongBinary como el tipo de Variable en el cuadro de diálogo Agregar miembros Variable. ClassWizard, a continuación, agregará una llamada RFX_LongBinary a la llamada de DoFieldExchange y incrementar el número total de campos enlazados.

Para actualizar datos mucho a los valores de la columna, asegúrese primero el asignado HGLOBAL es suficientemente grande para contener los nuevos datos llamando a :: GlobalSize del miembro m_hData de la CLongBinary. Si es demasiado pequeño, suelte el HGLOBAL y asignar un tamaño adecuado. A continuación, establezca m_dwDataLength para reflejar el nuevo tamaño.

De lo contrario, si m_dwDataLength es mayor que el tamaño de los datos que está reemplazando, puede libre y reasignar el HGLOBALo dejarlo asignados. Asegúrese de indicar el número de bytes utilizados efectivamente en m_dwDataLength.

Cómo actualizar un CLongBinary funciona

No es necesario entender cómo funciona la actualización de un CLongBinary , pero puede ser útil como un ejemplo de cómo enviar valores de datos long a un origen de datos, si elige este método tercero, se describe a continuación.

&Notanbsp;  Para que un campo de CLongBinary que deben incluirse en una actualización, debe llamar explícitamente SetFieldDirty para el campo. Si realiza cualquier cambio en un campo, incluido el establecimiento es Null, se debe llamar a SetFieldDirty.

Al actualizar un campo CLongBinary , las clases de base de datos utilizan el mecanismo DATA_AT_EXEC de ODBC (consulte la documentación de ODBC SQLSetPosdel argumento de rgbValue). Cuando el marco prepara la inserción o instrucción de actualización, en lugar de apuntar a la HGLOBAL que contiene los datos, la dirección de la CLongBinary se define como el valor de la columna en su lugar, y el indicador de longitud establecida en SQL_DATA_AT_EXEC. Más tarde, cuando la instrucción update es enviada al origen de datos, SQLExecDirect devolverá valor SQL_NEED_DATA. Esto advierte el marco que el valor de los parámetros de esta columna es realmente la dirección de un CLongBinary. El marco llama SQLGetData una vez con un pequeño buffer, esperando el controlador para devolver la longitud real de los datos. Si el controlador devuelve la longitud real del objeto binario grande (BLOB), MFC reasigna tanto espacio como sea necesario para recuperar el BLOB. Si el origen de datos devuelve SQL_NO_TOTAL, que indica que no se puede determinar el tamaño de la Mancha, MFC creará bloques más pequeños. El tamaño inicial por defecto es 64 K y bloques posteriores será el doble del tamaño; por ejemplo, la segunda será de 128 K, la tercera es 256 K y así sucesivamente. El tamaño inicial es configurable.

No vinculante: Recuperar y enviar datos directamente desde ODBC con SQLGetData

Con este método usted completamente saltarse las clases de base de datos y lidiar con la columna de datos long usted mismo.

Ventajas:

Puede almacenar en caché los datos en el disco si es necesario, o decidir dinámicamente la cantidad de datos para recuperar.

Desventajas:

No obtendrá apoyo AddNew o Editar el marco, y se debe escribir código para realizar las funciones básicas (Eliminar trabajo aunque, ya que no es una operación de nivel de columna).

En este caso, la columna de datos long debe estar en la lista de selección de registros, pero no debería obligarse a por el marco. Una forma de hacerlo es suministrar su propia instrucción SQL a través de GetDefaultSQL o como argumento a la función Open de CRecordsetlpszSQL y no enlazar la columna adicional con una llamada a la función RFX_. ODBC requiere que campos independientes aparecen a la derecha de campos enlazados, así que agregue sus columnas independientes hasta el final de la lista de selección.

Advertencianbsp;  Desde su columna de datos long no está obligada por el marco, los cambios no se manejará con llamadas de CRecordset:: Update . Debe crear y enviar las declaraciones SQL I&NSERT y UPDATE requiere usted mismo.

&Notas técnicas por número |nbsp; Notas técnicas por categoría

Index