Cette note décrit comment récupérer et envoyer les types de données ODBC SQL_LONGVARCHAR et SQL_LONGVARBINARY en utilisant les classes de base de données MFC.
Aperçu du Long Varchar/Varbinary soutien
Les types de données ODBC SQL_LONG_VARCHAR et SQL_LONGBINARY (appelés ici depuis longtemps les colonnes de données) peuvent contenir des quantités énormes de données. Il existe 3 façons vous pouvez gérer ces données:
Colonnes de données longues ne sont pas supportés pour les paramètres d'une requête. Ils sont uniquement pris en charge pour outputColumns.
Lie une longue colonne de données à une CString/CByteArray
Avantages:
Cette approche est simple à comprendre, et vous travaillez avec les classes de familiers. Le cadre fournit soutien CFormView pour CString avec DDX_Text. Vous avez beaucoup de chaîne générale ou des fonctionnalités de la collection avec le CString et les classes de CByteArray , et vous pouvez contrôler la quantité de mémoire allouée localement doit pour contenir la valeur de données. Le cadre tient à jour une ancienne copie des données de terrain pendant Edit ou AddNew des appels de fonction et le cadre peut détecter automatiquement les modifications de données pour vous.
&Notenbsp ;CString est conçu pour travailler sur les données de type caractère et CByteArray pour travailler sur des données binaires, il est recommandé que vous mettre les données de type caractère (SQL_LONGVARCHAR) dans CStringet les données binaires (SQL_LONGVARBINARY) dans CByteArray.
Les fonctions RFX pour CString et CByteArray ont un argument supplémentaire qui vous permet de substituer la taille par défaut de la mémoire allouée pour contenir la valeur récupérée pour la colonne de données. Note de l'argument nMaxLength dans les déclarations suivantes de la fonction:
vOID AFXAPI RFX_Text(CFieldExchange* pFX, const char *szName,
nbsp ; CString & valeur, int nMaxLength = 255, int nColumnType =
SQL_VARCHAR) ;
VOID AFXAPI RFX_Binary(CFieldExchange* pFX, const char *szName, CByteArray& value,int nMaxLength = 255)
Si vous récupérez une colonne de données long dans une CString ou CByteArray, le maximum revient quantité de données est, par défaut, 255 octets. Quelque chose au-delà de cela est ignoré. Dans ce cas, le cadre lève l'exception AFX_SQL_ERROR_DATA_TRUNCATED. Heureusement, vous pouvez augmenter explicitement nMaxLength de valeurs plus élevées, jusqu'à MAXINT.
ClassWizard lierez un SQL_LONGVARCHAR à une CString, ou un SQL_LONGVARBINARY à un CByteArray pour vous. Si vous souhaitez allouer plus de 255 octets, dans laquelle vous récupérez votre colonne de données long, vous pouvez ensuite fournir une valeur explicite pour nMaxLength.
Lorsqu'une colonne de données long est liée à une CString ou CByteArray, mise à jour le champ fonctionne exactement de la même que lorsqu'elle est liée à un SQL_VARCHAR ou SQL_VARBINARY. Pendant Modifier, la valeur de données est mis en cache plus loin et comparativement plus tard lors de la mise à jour est appelée pour détecter des modifications apportées à la valeur de données et définir les valeurs sale et Null pour la colonne appropriée.
Lie une longue colonne de données à un CLongBinary
Si votre colonne de données long peut-être contenir plus MAXINT octets de données, vous devez envisager probablement récupérer dans un CLongBinary.
Avantages:
Il récupère une colonne d'ensemble de données longues - jusqu'à la mémoire disponible.
Inconvénients:
Les données sont conservées en mémoire. Cette approche est aussi prohibitif pour très grandes quantités de données. Vous devez appeler SetFieldDirty pour le membre de données liées à s'assurer que le champ est inclus dans une opération de mise à jour.
Si vous récupérez des colonnes de données long dans un CLongBinary, les classes de base de données seront vérifier la taille totale de la colonne de données long, puis allouer un segment de mémoire HGLOBAL suffisamment grand pour maintenir la valeur de l'ensemble de données. Les classes de base de données puis extraire la valeur de données entière dans la alloué HGLOBAL.
Si la source de données ne peut pas retourner la taille attendue de la colonne de données long, le cadre lève l'exception AFX_SQL_ERROR_SQL_NO_TOTAL. Si la tentative d'allouer le HGLOBAL échoue, une exception de mémoire standard est levée.
ClassWizard lierez un SQL_LONGVARCHAR ou SQL_LONGVARBINARY à un CLongBinary pour vous. Sélectionnez le Type de Variable dans la boîte de dialogue Ajouter une Variable membre CLongBinary . ClassWizard est ensuite ajouter un appel RFX_LongBinary à votre appel de DoFieldExchange et incrémenter le nombre total de champs liés.
Pour mettre à jour les valeurs de colonne données depuis longtemps, tout d'abord vous assurer que le alloué HGLOBAL est assez grande pour contenir vos nouvelles données en appelant :: GlobalSize sur le membre m_hData de la CLongBinary. Si c'est trop petit, libérer le HGLOBAL et allouer un la taille appropriée. Ensuite la valeur m_dwDataLength pour refléter la nouvelle taille.
Sinon, si m_dwDataLength est plus grande que la taille des données que vous êtes remplaçant, vous pouvez gratuitement et réaffecter le HGLOBALou laisser alloué. Assurez-vous d'indiquer le nombre d'octets effectivement utilisées dans m_dwDataLength.
Comment mise à jour un CLongBinary fonctionne
Il n'est pas nécessaire de comprendre comment mettre à jour un CLongBinary fonctionne, mais il peut être utile à titre d'exemple sur la façon d'envoyer des valeurs de données longues à une source de données, si vous choisissez cette troisième méthode, décrite ci-dessous.
&Notenbsp ; Pour qu'un champ CLongBinary être inclus dans une mise à jour, vous devez appeler explicitement SetFieldDirty pour le champ. Si vous apportez toute modification à un champ, y compris la mise en valeur Null, vous devez appeler SetFieldDirty.
Lors de la mise à jour d'un champ CLongBinary , les classes de base de données utilisent mécanisme DATA_AT_EXEC de ODBC (voir documentation ODBC SQLSetPosdu rgbValue argument). Quand le cadre prépare à l'insertion ou mise à jour de déclaration, au lieu de pointer vers le HGLOBAL contenant les données, l' adresse de la CLongBinary est définie comme la valeur de la colonne au lieu de cela, et l'indicateur de longueur valeur SQL_DATA_AT_EXEC. Plus tard, lorsque l'instruction update est envoyée à la source de données, SQLExecDirect retourne SQL_NEED_DATA. Cette alerte le cadre que la valeur de la param pour cette colonne est en fait l'adresse d'un CLongBinary. Le cadre appelle SQLGetData une fois avec un petit tampon, attendent le conducteur pour retourner la longueur réelle des données. Si le pilote renvoie la longueur réelle de l'objet binaire volumineux (BLOB), MFC réalloue autant d'espace que nécessaire pour aller chercher le BLOB. Si la source de données retourne SQL_NO_TOTAL, indiquant qu'il ne peut pas déterminer la taille du BLOB, MFC va créer des blocs plus petits. La taille initiale par défaut est 64 K et blocs subséquents seront doubler la taille ; par exemple, la seconde sera 128 K, le troisième est de 256 K et ainsi de suite. La taille initiale est configurable.
Ne pas obligatoire : Récupération et envoi de données directement à partir de ODBC avec SQLGetData
Avec cette méthode vous complètement ignorer les classes de base de données et traitent de la colonne de données long vous-même.
Avantages:
Vous pouvez mettre en cache disque si nécessaire, ou déterminer dynamiquement la quantité de données pour extraire des données.
Inconvénients:
Vous n'obtenez pas du cadre Edit ou AddNew soutien, et vous devez écrire le code vous-même pour exécuter les fonctionnalités de base (Delete fonctionne bien, car il n'est pas une opération de niveau colonne).
Dans ce cas, la colonne de données longue doit être dans la liste select de l'objet recordset, mais il ne doit pas être liée par le cadre. Une façon d'y parvenir est de fournir votre propre instruction SQL via GetDefaultSQL ou comme argument lpszSQL de la fonction Open de CRecordsetet pas lier la colonne supplémentaire avec un appel de fonction RFX_. ODBC exige que les champs non liés apparaissent à droite des champs liés, ajoutez vos colonnes non liées à la fin de la liste de sélection.
Avertissementnbsp ; Puisque votre colonne de données long n'est pas lié par le cadre, modifications ne seront pas traitées avec CRecordset::Update appels. Vous devez créer et envoyer les instructions SQL I&NSERT et UPDATE requises vous-même.
&Notes techniques par le numéro |nbsp ; Notes techniques par catégorie