TN045: supporto di MFC/database per Long Varchar/Varbinary

Nota

La seguente nota tecnica non è stata aggiornata da quando è stata inclusa per la prima volta nella documentazione online. Di conseguenza, alcune procedure e argomenti potrebbero essere non aggiornati o errati. Per le informazioni più recenti, è consigliabile cercare l'argomento di interesse nell'indice della documentazione online.

Questa nota descrive come recuperare e inviare i tipi di dati odbc SQL_LONGVARCHAR e SQL_LONGVARBINARY usando le classi di database MFC.

Panoramica del supporto di Long Varchar/Varbinary

I tipi di dati ODBC SQL_LONG_VARCHAR e SQL_LONGBINARY (definiti qui per quanto tempo le colonne di dati) possono contenere grandi quantità di dati. Esistono tre modi per gestire questi dati:

  • Associarlo a un oggetto CString/CByteArray.

  • Associarlo a un oggetto CLongBinary.

  • Non associarlo affatto e recuperare e inviare manualmente il valore di dati lungo, indipendentemente dalle classi di database.

Ognuno dei tre metodi presenta vantaggi e svantaggi.

Le colonne di dati lunghe non sono supportate per i parametri di una query. Sono supportati solo per outputColumns.

Associazione di una colonna di dati long a CString/CByteArray

Vantaggi:

Questo approccio è semplice da comprendere e si lavora con classi familiari. Il framework fornisce CFormView supporto per CString con DDX_Text. Sono disponibili numerose funzionalità generali di stringa o raccolta con le CString classi e CByteArray ed è possibile controllare la quantità di memoria allocata localmente per contenere il valore dei dati. Il framework gestisce una copia precedente dei dati dei campi durante Edit o AddNew chiamate di funzione e il framework può rilevare automaticamente le modifiche ai dati.

Nota

Poiché CString è progettato per lavorare sui dati di tipo carattere e CByteArray per lavorare sui dati binari, è consigliabile inserire i dati di tipo carattere (SQL_LONGVARCHAR) in CStringe i dati binari (SQL_LONGVARBINARY) in CByteArray.

Le funzioni RFX per CString e CByteArray hanno un argomento aggiuntivo che consente di eseguire l'override delle dimensioni predefinite della memoria allocata per contenere il valore recuperato per la colonna di dati. Si noti l'argomento nMaxLength nelle dichiarazioni di funzione seguenti:

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

Se si recupera una colonna di dati lunga in un CString oggetto o CByteArray, la quantità massima di dati restituita è, per impostazione predefinita, di 255 byte. Tutto ciò che non va oltre questo viene ignorato. In questo caso, il framework genererà l'eccezione AFX_SQL_ERROR_DATA_TRUNCATED. Fortunatamente, è possibile aumentare in modo esplicito nMaxLength a valori maggiori, fino a MAXINT.

Nota

Il valore di nMaxLength viene usato da MFC per impostare il buffer locale della SQLBindColumn funzione. Si tratta del buffer locale per l'archiviazione dei dati e non influisce effettivamente sulla quantità di dati restituiti dal driver ODBC. RFX_Text e RFX_Binary effettuano una sola chiamata usando SQLFetch per recuperare i dati dal database back-end. Ogni driver ODBC presenta una limitazione diversa per la quantità di dati che possono restituire in un singolo recupero. Questo limite può essere molto inferiore al valore impostato in nMaxLength, nel qual caso verrà generata l'eccezione AFX_SQL_ERROR_DATA_TRUNCATED . In queste circostanze, passare all'uso RFX_LongBinary invece di RFX_Text o RFX_Binary in modo che tutti i dati possano essere recuperati.

ClassWizard associa un SQL_LONGVARCHAR a un CStringoggetto o un SQL_LONGVARBINARY a un oggetto CByteArray per l'utente. Se si desidera allocare più di 255 byte in cui si recupera la colonna di dati lunga, è possibile specificare un valore esplicito per nMaxLength.

Quando una colonna di dati lunga è associata a o CString CByteArray, l'aggiornamento del campo funziona esattamente come quando è associato a un SQL_VARCHAR o SQL_VARBINARY. Durante Edit, il valore dei dati viene memorizzato nella cache e successivamente confrontato quando viene chiamato per Update rilevare le modifiche apportate al valore dei dati e impostare i valori Dirty e Null per la colonna in modo appropriato.

Associazione di una colonna di dati long a un CLongBinary

Se la colonna di dati lunga può contenere più byte MAXINT di dati, è consigliabile recuperarla in un oggetto CLongBinary.

Vantaggi:

In questo modo viene recuperata un'intera colonna di dati lunga, fino alla memoria disponibile.

Svantaggi:

I dati sono contenuti in memoria. Questo approccio è anche eccessivamente costoso per grandi quantità di dati. È necessario chiamare SetFieldDirty il membro dati associato per assicurarsi che il campo sia incluso in un'operazione Update .

Se si recuperano colonne di dati lunghe in un CLongBinary, le classi di database verificheranno le dimensioni totali della colonna di dati lunga, quindi allocare un HGLOBAL segmento di memoria sufficientemente grande da contenere l'intero valore di dati. Le classi di database recuperano quindi l'intero valore di dati nell'oggetto allocato HGLOBAL.

Se l'origine dati non può restituire le dimensioni previste della colonna di dati lunga, il framework genererà l'eccezione AFX_SQL_ERROR_SQL_NO_TOTAL. Se il tentativo di allocare l'oggetto ha esito negativo, viene generata un'eccezione HGLOBAL di memoria standard.

ClassWizard associa un SQL_LONGVARCHAR o SQL_LONGVARBINARY a un oggetto per l'utente CLongBinary . Selezionare CLongBinary come tipo di variabile nella finestra di dialogo Aggiungi variabile membro. ClassWizard aggiungerà quindi una RFX_LongBinary chiamata alla DoFieldExchange chiamata e incrementerà il numero totale di campi associati.

Per aggiornare i valori delle colonne di dati lunghe, assicurarsi prima di tutto che l'oggetto allocato HGLOBAL sia sufficientemente grande da contenere i nuovi dati chiamando ::GlobalSize nel membro m_hData dell'oggetto CLongBinary. Se è troppo piccolo, rilasciare HGLOBAL e allocare una delle dimensioni appropriate. Impostare quindi m_dwDataLength per riflettere le nuove dimensioni.

In caso contrario, se m_dwDataLength è maggiore delle dimensioni dei dati che si sta sostituendo, è possibile liberare e riallocare o HGLOBALlasciarli allocati. Assicurarsi di indicare il numero di byte effettivamente utilizzati in m_dwDataLength.

Funzionamento dell'aggiornamento di un CLongBinary

Non è necessario comprendere il funzionamento di un CLongBinary oggetto, ma può essere utile come esempio su come inviare valori di dati lunghi a un'origine dati, se si sceglie questo terzo metodo, descritto di seguito.

Nota

Affinché un CLongBinary campo venga incluso in un aggiornamento, è necessario chiamare SetFieldDirty in modo esplicito il campo. Se si apporta una modifica a un campo, inclusa l'impostazione null, è necessario chiamare SetFieldDirty. È inoltre necessario chiamare SetFieldNull, con il secondo parametro fal edizione Standard, per contrassegnare il campo come valore.

Quando si aggiorna un CLongBinary campo, le classi di database usano il meccanismo di DATA_AT_EXEC ODBC (vedere la documentazione ODBC sull'argomento SQLSetPosrgbValue). Quando il framework prepara l'istruzione insert o update, anziché puntare all'oggetto HGLOBAL contenente i dati, l'indirizzo di CLongBinary viene impostato come valore della colonna e l'indicatore di lunghezza impostato su SQL_DATA_AT_EXEC. Successivamente, quando l'istruzione update viene inviata all'origine dati, SQLExecDirect restituirà SQL_Nedizione EnterpriseD_DATA. In questo modo il framework avvisa che il valore del parametro per questa colonna è effettivamente l'indirizzo di un oggetto CLongBinary. Il framework chiama SQLGetData una volta con un buffer piccolo, prevedendo che il driver restituisca la lunghezza effettiva dei dati. Se il driver restituisce la lunghezza effettiva dell'oggetto binario di grandi dimensioni (BLOB), MFC rialloca la quantità di spazio necessaria per recuperare il BLOB. Se l'origine dati restituisce SQL_NO_TOTAL, a indicare che non è in grado di determinare le dimensioni del BLOB, MFC creerà blocchi più piccoli. La dimensione iniziale predefinita è 64K e i blocchi successivi saranno raddoppiati; ad esempio, il secondo sarà 128K, il terzo è 256K e così via. Le dimensioni iniziali sono configurabili.

Not Binding: recupero/invio di dati direttamente da ODBC con SQLGetData

Con questo metodo è possibile ignorare completamente le classi di database e gestire manualmente la colonna di dati lunga.

Vantaggi:

È possibile memorizzare nella cache i dati su disco, se necessario, o decidere in modo dinamico la quantità di dati da recuperare.

Svantaggi:

Non si ottiene il supporto o AddNew il framework Edit ed è necessario scrivere il codice manualmente per eseguire funzionalità di base (Delete funziona tuttavia, poiché non è un'operazione a livello di colonna).

In questo caso, la colonna di dati lunga deve trovarsi nell'elenco di selezione del recordset, ma non deve essere associata al framework. Un modo per eseguire questa operazione consiste nell'fornire un'istruzione SQL personalizzata tramite GetDefaultSQL o come argomento lpszSQL alla CRecordsetfunzione di Open e non associare la colonna aggiuntiva a una chiamata di funzione RFX_. ODBC richiede che i campi non associati vengano visualizzati a destra dei campi associati, quindi aggiungere la colonna o le colonne non associate alla fine dell'elenco di selezione.

Nota

Poiché la colonna di dati lunga non è associata al framework, le modifiche apportate non verranno gestite con CRecordset::Update le chiamate. È necessario creare e inviare manualmente le istruzioni SQL IN edizione Standard RT e UPDATE necessarie.

Vedi anche

Note tecniche per numero
Note tecniche per categoria