TN043: routine RFX

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 l'architettura RFX (Record Field Exchange). Viene inoltre descritto come scrivere una routine RFX_ .

Panoramica di Record Field Exchange

Tutte le funzioni di campo del recordset vengono eseguite con il codice C++. Non ci sono risorse speciali o macro magiche. Il cuore del meccanismo è una funzione virtuale che deve essere sottoposta a override in ogni classe di recordset derivata. Si trova sempre in questo formato:

void CMySet::DoFieldExchange(CFieldExchange* pFX)
{
    //{{AFX_FIELD_MAP(CMySet)
        <recordset exchange field type call>
        <recordset exchange function call>
    //}}AFX_FIELD_MAP
}

Il formato speciale I commenti AFX consentono a ClassWizard di individuare e modificare il codice all'interno di questa funzione. Il codice non compatibile con ClassWizard deve essere inserito all'esterno dei commenti in formato speciale.

Nell'esempio precedente, <recordset_exchange_field_type_call> è nel formato :

pFX->SetFieldType(CFieldExchange::outputColumn);

e <recordset_exchange_function_call> è nel formato:

RFX_Custom(pFX, "Col2", m_Col2);

La maggior parte delle funzioni RFX_ ha tre argomenti, come illustrato in precedenza, ma alcuni (ad esempio RFX_Text e RFX_Binary) hanno argomenti facoltativi aggiuntivi.

In ogni DoDataExchange funzione possono essere inclusi più RFX_.

Per un elenco di tutte le routine di scambio dei campi del recordset fornite con MFC, vedere 'afxdb.h'.

Le chiamate di campo del recordset sono un modo per registrare i percorsi di memoria (in genere i membri dati) per archiviare i dati dei campi per una CMySet classe.

Note

Le funzioni di campo dell'oggetto Recordset sono progettate per funzionare solo con le CRecordset classi . In genere non sono utilizzabili da altre classi MFC.

I valori iniziali dei dati vengono impostati nel costruttore C++ standard, in genere in un blocco con //{{AFX_FIELD_INIT(CMylSet) commenti e //}}AFX_FIELD_INIT .

Ogni RFX_ funzione deve supportare varie operazioni, tra cui la restituzione dello stato dirty del campo all'archiviazione del campo in preparazione alla modifica del campo.

Ogni funzione che chiama DoFieldExchange (ad esempio SetFieldNull, IsFieldDirty), esegue la propria inizializzazione intorno alla chiamata a DoFieldExchange.

Funzionamento

Non è necessario comprendere quanto segue per usare lo scambio di campi di record. Tuttavia, capire come funziona dietro le quinte ti aiuterà a scrivere la tua procedura di scambio.

La DoFieldExchange funzione membro è molto simile alla Serialize funzione membro, è responsabile del recupero o dell'impostazione di dati da/verso una maschera esterna (in questo caso colonne dal risultato di una query ODBC) dai/ai dati dei membri nella classe . Il parametro pFX è il contesto per lo scambio di dati ed è simile al parametro CArchive a CObject::Serialize. PFX (oggetto CFieldExchange ) ha un indicatore dell'operazione, simile a , ma una generalizzazione del flag di direzione CArchive. Una funzione RFX potrebbe dover supportare le operazioni seguenti:

  • BindParam — Indicare dove ODBC deve recuperare i dati dei parametri

  • BindFieldToColumn — Indica dove ODBC deve recuperare/depositare i dati outputColumn

  • Fixup — Impostare CString/CByteArray lunghezze, impostare il bit di stato NULL

  • MarkForAddNew — Contrassegnare dirty se il valore è stato modificato dopo La nuova chiamata a AddNew

  • MarkForUpdate — Contrassegnare dirty se il valore è stato modificato dopo la modifica della chiamata

  • Name — Aggiungere nomi di campo per i campi contrassegnati come dirty

  • NameValue — Aggiungere "<column name>=" per i campi contrassegnati come dirty

  • Value — Aggiungere "" seguito da separatore, ad esempio ',' o '

  • SetFieldDirty — Imposta il bit di stato dirty (ad esempio modificato) campo

  • SetFieldNull — Impostare il bit di stato che indica il valore Null per il campo

  • IsFieldDirty — Valore restituito del bit di stato dirty

  • IsFieldNull — Valore restituito di bit di stato Null

  • IsFieldNullable — Restituisce TRUE se il campo può contenere valori NULL

  • StoreField — Valore campo archivio

  • LoadField — Ricaricare il valore del campo archiviato

  • GetFieldInfoValue — Restituire informazioni generali su un campo

  • GetFieldInfoOrdinal — Restituire informazioni generali su un campo

Estensioni utente

Esistono diversi modi per estendere il meccanismo RFX predefinito. È possibile

  • Aggiungere nuovi tipi di dati. Ad esempio:

    CBookmark
    
  • Aggiungere nuove procedure di scambio (RFX_).

    void AFXAPI RFX_Bigint(CFieldExchange* pFX,
        const char *szName,
        BIGINT& value);
    
  • Fare in modo che la DoFieldExchange funzione membro includa in modo condizionale chiamate RFX aggiuntive o qualsiasi altra istruzione C++ valida.

    while (posExtraFields != NULL)
    {
        RFX_Text(pFX,
        m_listName.GetNext(posExtraFields),
        m_listValue.GetNext(posExtraValues));
    }
    

Nota

Tale codice non può essere modificato da ClassWizard e deve essere utilizzato solo all'esterno dei commenti in formato speciale.

Scrittura di un RFX personalizzato

Per scrivere una funzione RFX personalizzata, è consigliabile copiare una funzione RFX esistente e modificarla ai propri scopi. Se si seleziona il file RFX corretto da copiare, il processo può risultare molto più semplice. Alcune funzioni RFX hanno alcune proprietà univoce da tenere in considerazione quando si decide quale copiare.

RFX_Long e RFX_Int: queste sono le funzioni RFX più semplici. Il valore dei dati non richiede alcuna interpretazione speciale e le dimensioni dei dati sono fisse.

RFX_Single e RFX_Double: come RFX_Long e RFX_Int sopra, queste funzioni sono semplici e possono usare ampiamente l'implementazione predefinita. Vengono archiviati in dbflt.cpp anziché in dbrfx.cpp, tuttavia, per abilitare il caricamento della libreria a virgola mobile di runtime solo quando fanno riferimento in modo esplicito.

RFX_Text e RFX_Binary: queste due funzioni preallocano un buffer statico per contenere informazioni stringa/binarie e devono registrare questi buffer con ODBC SQLBindCol invece di registrare &value. Per questo motivo, queste due funzioni hanno un sacco di codice caso speciale.

RFX_Date: ODBC restituisce informazioni di data e ora nella struttura dei dati TIMESTAMP_STRUCT. Questa funzione alloca dinamicamente un TIMESTAMP_STRUCT come "proxy" per l'invio e la ricezione di dati di data e ora. Varie operazioni devono trasferire le informazioni di data e ora tra l'oggetto C++ CTime e il proxy TIMESTAMP_STRUCT. Questo complica notevolmente questa funzione, ma è un buon esempio di come usare un proxy per il trasferimento dei dati.

RFX_LongBinary: questa è l'unica funzione RFX della libreria di classi che non usa l'associazione di colonne per ricevere e inviare dati. Questa funzione ignora l'operazione BindFieldToColumn e, durante l'operazione Fixup, alloca l'archiviazione per contenere i dati SQL_LONGVARCHAR in ingresso o SQL_LONGVARBINARY, quindi esegue una chiamata SQLGetData per recuperare il valore nell'archiviazione allocata. Quando si prepara a inviare i valori dei dati all'origine dati (ad esempio, le operazioni NameValue e Value), questa funzione usa la funzionalità di DATA_AT_EXEC ODBC. Per altre informazioni sull'uso di SQL_LONGVARBINARY e SQL_LONGVARCHARs, vedere La nota tecnica 45 .

Quando si scrive una funzione di RFX_ personalizzata, spesso sarà possibile usare CFieldExchange::Default per implementare una determinata operazione. Esaminare l'implementazione di Default per l'operazione in questione. Se esegue l'operazione scritta nella funzione RFX_ , è possibile delegare a CFieldExchange::Default. È possibile visualizzare esempi di chiamata CFieldExchange::Default in dbrfx.cpp

È importante chiamare IsFieldType all'inizio della funzione RFX e restituire immediatamente se restituisce FAL edizione Standard. Questo meccanismo impedisce l'esecuzione delle operazioni dei parametri su outputColumns e viceversa ,ad esempio la chiamata BindParam a un outputColumn. Inoltre, IsFieldType tiene traccia automaticamente del numero di outputColumns (m_nFields) e dei parametri (m_nParams).

Vedi anche

Note tecniche per numero
Note tecniche per categoria