Bagikan melalui


TN043: Rutinitas RFX

Catatan

Catatan teknis berikut belum diperbarui sejak pertama kali disertakan dalam dokumentasi online. Akibatnya, beberapa prosedur dan topik mungkin kedaluarsa atau salah. Untuk informasi terbaru, disarankan agar Anda mencari topik yang menarik dalam indeks dokumentasi online.

Catatan ini menjelaskan arsitektur pertukaran bidang rekaman (RFX). Ini juga menjelaskan bagaimana Anda menulis prosedur RFX_ .

Gambaran Umum Pertukaran Bidang Rekaman

Semua fungsi bidang recordset dilakukan dengan kode C++. Tidak ada sumber daya khusus atau makro ajaib. Inti mekanisme adalah fungsi virtual yang harus ditimpa di setiap kelas recordset turunan. Ini selalu ditemukan dalam bentuk ini:

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

Format khusus komentar AFX memungkinkan ClassWizard menemukan dan mengedit kode dalam fungsi ini. Kode yang tidak kompatibel dengan ClassWizard harus ditempatkan di luar komentar format khusus.

Dalam contoh di atas, <recordset_exchange_field_type_call> dalam formulir:

pFX->SetFieldType(CFieldExchange::outputColumn);

dan <recordset_exchange_function_call> dalam bentuk:

RFX_Custom(pFX, "Col2", m_Col2);

Sebagian besar fungsi RFX_ memiliki tiga argumen seperti yang ditunjukkan di atas, tetapi beberapa (misalnya RFX_Text dan RFX_Binary) memiliki argumen opsional tambahan.

Lebih dari satu RFX_ dapat disertakan dalam setiap DoDataExchange fungsi.

Lihat 'afxdb.h' untuk daftar semua rutinitas pertukaran bidang recordset yang disediakan dengan MFC.

Panggilan bidang recordset adalah cara mendaftarkan lokasi memori (biasanya anggota data) untuk menyimpan data bidang untuk kelas CMySet .

Catatan

Fungsi bidang recordset dirancang untuk hanya berfungsi dengan CRecordset kelas. Mereka umumnya tidak dapat digunakan oleh kelas MFC lainnya.

Nilai awal data diatur dalam konstruktor C++ standar, biasanya dalam blok dengan //{{AFX_FIELD_INIT(CMylSet) komentar dan //}}AFX_FIELD_INIT .

Setiap fungsi RFX_ harus mendukung berbagai operasi, mulai dari mengembalikan status kotor bidang hingga pengarsipan bidang sebagai persiapan untuk mengedit bidang.

Setiap fungsi yang memanggil (misalnya , ), melakukan inisialisasinya DoFieldExchange sendiri di sekitar panggilan ke DoFieldExchange. IsFieldDirtySetFieldNull

Bagaimana Cara Kerjanya

Anda tidak perlu memahami hal berikut untuk menggunakan pertukaran bidang rekaman. Namun, memahami cara kerjanya di belakang layar akan membantu Anda menulis prosedur pertukaran Anda sendiri.

Fungsi DoFieldExchange anggota mirip dengan Serialize fungsi anggota — bertanggung jawab untuk mendapatkan atau mengatur data ke/dari formulir eksternal (dalam hal ini kolom dari hasil kueri ODBC) dari/ke data anggota di kelas. Parameter pFX adalah konteks untuk melakukan pertukaran data dan mirip dengan parameter CArchive dengan CObject::Serialize. pFX (CFieldExchangeobjek) memiliki indikator operasi, yang mirip dengan, tetapi generalisasi bendera arah CArchive. Fungsi RFX mungkin harus mendukung operasi berikut:

  • BindParam — Menunjukkan di mana ODBC harus mengambil data parameter

  • BindFieldToColumn — Menunjukkan di mana ODBC harus mengambil/mendepositkan data outputColumn

  • Fixup — Atur CString/CByteArray panjang, atur bit status NULL

  • MarkForAddNew — Tandai kotor jika nilai telah berubah sejak AddNew call

  • MarkForUpdate — Tandai kotor jika nilai telah berubah sejak Edit panggilan

  • Name — Tambahkan nama bidang untuk bidang yang ditandai kotor

  • NameValue — Tambahkan "<nama> kolom=" untuk bidang yang ditandai kotor

  • Value — Tambahkan "" diikuti oleh pemisah, seperti ',' atau ' '

  • SetFieldDirty — Atur status bit kotor (yaitu diubah) bidang

  • SetFieldNull — Atur bit status yang menunjukkan nilai null untuk bidang

  • IsFieldDirty — Mengembalikan nilai bit status kotor

  • IsFieldNull — Mengembalikan nilai bit status null

  • IsFieldNullable — Mengembalikan TRUE jika bidang dapat menyimpan nilai NULL

  • StoreField — Nilai bidang arsip

  • LoadField — Muat ulang nilai bidang yang diarsipkan

  • GetFieldInfoValue — Mengembalikan informasi umum pada bidang

  • GetFieldInfoOrdinal — Mengembalikan informasi umum pada bidang

Ekstensi Pengguna

Ada beberapa cara untuk memperluas mekanisme RFX default. Anda dapat

  • Tambahkan jenis data baru. Misalnya:

    CBookmark
    
  • Tambahkan prosedur pertukaran baru (RFX_).

    void AFXAPI RFX_Bigint(CFieldExchange* pFX,
        const char *szName,
        BIGINT& value);
    
  • Minta anggota DoFieldExchange berfungsi secara kondisional menyertakan panggilan RFX tambahan atau pernyataan C++ lain yang valid.

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

Catatan

Kode tersebut tidak dapat diedit oleh ClassWizard dan harus digunakan hanya di luar komentar format khusus.

Menulis RFX Kustom

Untuk menulis fungsi RFX Kustom Anda sendiri, disarankan agar Anda menyalin fungsi RFX yang ada dan memodifikasinya ke tujuan Anda sendiri. Memilih RFX yang tepat untuk disalin dapat membuat pekerjaan Anda jauh lebih mudah. Beberapa fungsi RFX memiliki beberapa properti unik yang harus Anda perhitungkan saat memutuskan mana yang akan disalin.

RFX_Long dan RFX_Int: Ini adalah fungsi RFX paling sederhana. Nilai data tidak memerlukan interpretasi khusus, dan ukuran data diperbaiki.

RFX_Single dan RFX_Double: Seperti RFX_Long dan RFX_Int di atas, fungsi-fungsi ini sederhana dan dapat menggunakan implementasi default secara ekstensif. Mereka disimpan dalam dbflt.cpp alih-alih dbrfx.cpp, namun, untuk mengaktifkan pemuatan pustaka titik float runtime hanya ketika mereka secara eksplisit mereferensikan.

RFX_Text dan RFX_Binary: Kedua fungsi ini melakukan prealokasi buffer statis untuk menyimpan informasi string/biner, dan harus mendaftarkan buffer ini dengan ODBC SQLBindCol alih-alih mendaftarkan &value. Karena itu, kedua fungsi ini memiliki banyak kode kasus khusus.

RFX_Date: ODBC mengembalikan informasi tanggal dan waktu dalam struktur data TIMESTAMP_STRUCT mereka sendiri. Fungsi ini secara dinamis mengalokasikan TIMESTAMP_STRUCT sebagai "proksi" untuk mengirim dan menerima data waktu tanggal. Berbagai operasi harus mentransfer informasi tanggal dan waktu antara objek C++ CTime dan proksi TIMESTAMP_STRUCT. Ini sangat mempersulit fungsi ini, tetapi ini adalah contoh yang baik tentang cara menggunakan proksi untuk transfer data.

RFX_LongBinary: Ini adalah satu-satunya fungsi RFX pustaka kelas yang tidak menggunakan pengikatan kolom untuk menerima dan mengirim data. Fungsi ini mengabaikan operasi BindFieldToColumn dan sebagai gantinya, selama operasi Perbaikan, mengalokasikan penyimpanan untuk menyimpan data SQL_LONGVARCHAR atau SQL_LONGVARBINARY masuk, lalu melakukan panggilan SQLGetData untuk mengambil nilai ke penyimpanan yang dialokasikan. Saat bersiap untuk mengirim nilai data kembali ke sumber data (seperti operasi NameValue dan Value), fungsi ini menggunakan fungsionalitas DATA_AT_EXEC ODBC. Lihat Catatan Teknis 45 untuk informasi selengkapnya tentang bekerja dengan SQL_LONGVARBINARY dan SQL_LONGVARCHARs.

Saat menulis fungsi RFX_ Anda sendiri, Anda akan sering dapat menggunakan CFieldExchange::Default untuk menerapkan operasi tertentu. Lihat implementasi Default untuk operasi yang dimaksud. Jika melakukan operasi, Anda akan menulis dalam fungsi RFX_ Anda, Anda dapat mendelegasikan ke CFieldExchange::Default. Anda dapat melihat contoh panggilan CFieldExchange::Default di dbrfx.cpp

Penting untuk memanggil IsFieldType di awal fungsi RFX Anda, dan segera kembali jika mengembalikan FALSE. Mekanisme ini menjaga operasi parameter tidak dilakukan pada outputColumns, dan sebaliknya (seperti memanggil BindParam pada outputColumn). Selain itu, IsFieldType secara otomatis melacak jumlah outputColumns (m_nFields) dan param (m_nParams).

Baca juga

Catatan Teknis menurut Angka
Catatan Teknis menurut Kategori