Partager via


TN045 : Prise en charge MFC/Database de longs varchar/varbinary

[!REMARQUE]

La note technique suivante n'a pas été modifiée depuis si c'était première inclus dans la documentation en ligne.Par conséquent, certaines procédures et rubriques peuvent être obsolètes ou incorrects.Pour obtenir les informations les plus récentes, il est recommandé que vous trouviez la rubrique d'intérêt dans l'index de la documentation en ligne.

Cette remarque décrit comment récupérer et envoyer les types de données ODBC SQL_LONGVARCHAR et de SQL_LONGVARBINARY à l'aide de les classes de base de données MFC.

Vue d'ensemble de longue prise en charge de varchar/varbinary

Les types de données ODBC SQL_LONG_VARCHAR et de SQL_LONGBINARY (appelés ici agit de colonnes de type long de données) peuvent contenir des montants considérables de données.Il y a 3 manières que vous pouvez traiter ces données :

  • Liez -le à CString/CByteArray.

  • Liez -le à CLongBinary.

  • Ne le liez pas du tout et ne récupérez pas et n'envoyez pas une longue valeur de données manuellement, indépendamment des classes de base de données.

Les trois méthodes a des avantages et des inconvénients.

Des colonnes de données ne sont pas prises en charge pour les paramètres à une requête.Elles sont pris en charge pour les outputColumns.

Lier une longue colonne de données à un CString/CByteArray

Avantages :

Cette approche est simple à inclure, et vous utilisez les classes familières.L'infrastructure fournit la prise en charge de CFormView d' CString avec DDX_Text.Vous avez beaucoup de fonctionnalité générale de chaîne ou de collection avec les classes d' CString et d' CByteArray , et vous pouvez contrôler la quantité de mémoire allouée localement pour contenir la valeur de données.L'infrastructure conserve une ancienne copie des données du champ durant Edit ou les appels de fonction d' AddNew , et l'infrastructure peut détecter automatiquement les modifications apportées aux données.

[!REMARQUE]

Étant donné qu' CString est conçu pour fonctionner sur les données caractères, et CByteArray pour travailler sur des données binaires, il est recommandé de mettre les données caractères (SQL_LONGVARCHAR) dans CString, et 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 de la mémoire allouée pour contenir la valeur récupérée pour la colonne de données.Notez l'argument de nMaxLength dans les déclarations de fonctions suivantes :

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);

Si vous extrayez une longue colonne de données dans CString ou CByteArray, le volume de données retournée par maximale est, par défaut, de 255 octets.Quelque chose au delà de ce est ignoré.Dans ce cas, l'infrastructure lève l'exception AFX_SQL_ERROR_DATA_TRUNCATED.Heureusement, vous pouvez explicitement augmenter le nMaxLength à des valeurs supérieures, jusqu'à MAXINT.

[!REMARQUE]

La valeur du nMaxLength est utilisée par les MFC pour définir la mémoire tampon locale de la fonction de SQLBindColumn .Il s'agit de la mémoire tampon locale pour le stockage des données et n'affecte pas la quantité de données retournées par le pilote ODBC.RFX_Text et RFX_Binary font uniquement un appel à SQLFetch pour récupérer les données de la base de données principale.Chaque pilote ODBC possède une limitation différente de la quantité de données qu'elles peuvent retourner dans une seule extraction.Cette limite peut être plus petite que la valeur définie dans le nMaxLength, auquel cas l'exception AFX_SQL_ERROR_DATA_TRUNCATED sera levée.Dans ces circonstances, commutateur à utiliser RFX_LongBinary au lieu d' RFX_Text ou d' RFX_Binary afin que toutes les données puissent être récupérées.

Assistant classe crée SQL_LONGVARCHAR à CString, ou SQL_LONGVARBINARY à CByteArray pour vous.Si vous souhaitez allouer plus de 255 octets dans lesquels vous récupérez votre longue colonne de données, vous pouvez ensuite fournir une valeur explicite pour le nMaxLength.

Lorsqu'une longue colonne de données est liée à CString ou à CByteArray, mettre à jour travail sur le mot simplement la même manière que lorsqu'il est lié à un SQL_VARCHAR ou à SQL_VARBINARY.Pendant le Edit, la valeur de données est mise en cache avant et ensuite comparée lorsque Mettre à jour est appelé pour détecter des modifications à la valeur de données et pour définir le modifié et les valeurs NULL pour la colonne correctement.

Lier une longue colonne de données à un CLongBinary

Si votre longue colonne de données peut contenir plus d'octets de MAXINT de données, vous devez envisager probablement de l'extraire vers CLongBinary.

Avantages :

Cela extrait une longue colonne de données entière, jusqu'à la mémoire.

Inconvénients :

Les données sont conservées en mémoire.Cette approche est également prohibitivement coûteuse de très grandes quantités de données.Vous devez appeler SetFieldDirty pour que le membre de données dépendantes tout le champ est inclus dans une opération de Mettre à jour .

Si vous extrayez des colonnes de données dans CLongBinary, les classes de base de données à la taille totale de la longue colonne de données, alors allouent un segment de mémoire de HGLOBAL assez grand pour le contenir la valeur de données entière.Les classes de base de données récupèrent la valeur de données entière dans HGLOBALalloué.

Si la source de données ne peut pas retourner la taille estimée de la longue colonne de données, l'infrastructure lève l'exception AFX_SQL_ERROR_SQL_NO_TOTAL.Si la tentative d'allocation HGLOBAL échoue, une exception standard de mémoire est levée.

Assistant classe crée SQL_LONGVARCHAR ou SQL_LONGVARBINARY à CLongBinary pour vous.Sélectionnez CLongBinary en tant que variable dans la boîte de dialogue de variable membre d'ajouter.ClassWizard ensuite ajoute un appel d' RFX_LongBinary à votre appel d' DoFieldExchange et incrémente tout le nombre de champs liés.

Pour mettre à jour des valeurs de colonne de données, vérifiez d'abord qu' HGLOBAL alloué est suffisamment grande pour contenir vos nouvelles données en appelant ::GlobalSize sur le membre d' m_hData d' CLongBinary.S'il est trop petite, relâchez HGLOBAL et allouez un la taille appropriée.m_dwDataLength définissez pour refléter la nouvelle taille.

Sinon, si m_dwDataLength est supérieure à la taille des données que vous remplacez, vous pouvez soit libérer et réaffecter HGLOBAL, ou laissez -le alloué.Veillez à indiquer le nombre d'octets réellement utilisés dans m_dwDataLength.

Comment mettre à jour un CLongBinary s'exécute

Il n'est pas nécessaire de comprendre comment mettre à jour CLongBinary s'exécute, mais il peut être utile comme exemple sur la manière d'envoyer des valeurs de données à une source de données, si vous choisissez cette troisième méthode, décrite ci-dessous.

[!REMARQUE]

Pour qu'un champ d' CLongBinary est inclus dans une mise à niveau, vous devez appeler explicitement SetFieldDirty pour le champ.Si vous apportez toute modification apportée à un champ, y compris le définir null, vous devez appeler SetFieldDirty.Vous devez également appeler SetFieldNull, avec le deuxième paramètre est FALSE, pour marquer le champ comme ayant une valeur.

En mettant à jour un champ d' CLongBinary , le mécanisme de DATA_AT_EXEC ODBC d'utilisation de classes de base de données (consultez la documentation ODBC sur l'argument du rgbValue de SQLSetPos).Lorsque l'infrastructure prépare l'insertion ou instruction UPDATE, au lieu de pointage à HGLOBAL qui contiennent des données, l'adresse d' CLongBinary est définie comme valeur de la colonne à la place, et indicateur de longueur défini à SQL_DATA_AT_EXEC.Ultérieurement, lorsque l'instruction UPDATE est envoyée à la source de données, SQLExecDirect retournera SQL_NEED_DATA.Cela alerte l'infrastructure que la valeur du param pour cette colonne est réellement l'adresse d' CLongBinary.L'infrastructure appelle SQLGetData une fois avec une petite mémoire tampon, le code qui s'attend à ce que le pilote retourne la longueur réelle des données.Si le pilote retourne la longueur réelle de l'objet BLOB (le BLOB), MFC réaffecte plus de place que nécessaire pour récupérer le binaire volumineux.Si la source de données retourne SQL_NO_TOTAL, indiquant qu'il ne peut pas déterminer la taille du binaire volumineux, MFC crée des plus petits blocs.La taille d'origine par défaut est limitée, et les blocs suivants seront double la taille ; par exemple, le deuxième est 128K, la troisième de 256K, et ainsi de suite.La taille initiale est configurable.

Ne liant pas : Données de récupérer/envoi direct ODBC avec SQLGetData

Avec cette méthode vous passez complètement les classes de base de données, et le cas avec une longue colonne de données.

Avantages :

Vous pouvez mettre en cache des données sur disque si nécessaire, ou décidez dynamiquement la quantité de données à récupérer.

Inconvénients :

Vous n'obtenez pas la prise en charge de Edit ou d' AddNew de l'infrastructure, et vous devez écrire le code vous-même pour exécuter les fonctionnalités de base (Delete fonctionne toutefois, étant donné que ce n'est pas une opération de niveau de colonne).

Dans ce cas, une longue colonne de données doit se trouver dans la liste de sélection du recordset, mais ne doit pas être liée à par l'infrastructure.Une façon de faire ceci consiste à fournir votre propre instruction SQL via GetDefaultSQL ou comme argument lpszSQL à la fonction de Ouvrir des CRecordset, et de ne pas lier la colonne supplémentaire avec un appel de fonction de RFX_.ODBC requiert que les champs indépendants s'affichent à droite des champs liés, donc ajoutez votre colonne ou colonne indépendante à la fin de la liste de sélection.

[!REMARQUE]

Étant donné que votre longue colonne de données n'est pas liée par l'infrastructure, les modifications apportées à elle ne seront pas gérées par des appels d' CRecordset::Update .Vous devez créer et envoyer SQL requis INSÉRER les instructions et pour METTRE À JOUR vous-même.

Voir aussi

Autres ressources

Notes techniques de nombres

Notes techniques de catégorie