Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Ada tiga skenario dasar di mana Anda perlu menggunakan beberapa pengakses:
Beberapa set baris baca/tulis. Dalam skenario ini, Anda memiliki tabel dengan kunci primer. Anda ingin dapat membaca semua kolom dalam baris, termasuk kunci utama. Anda juga ingin dapat menulis data ke semua kolom kecuali kunci utama (karena Anda tidak dapat menulis ke kolom kunci utama). Dalam hal ini, Anda menyiapkan dua aksesor:
Aksesor 0 berisi semua kolom.
Aksesor 1 berisi semua kolom kecuali kunci utama.
Performa. Dalam skenario ini, satu atau beberapa kolom memiliki sejumlah besar data, misalnya, file grafis, suara, atau video. Setiap kali Anda pindah ke baris, Anda mungkin tidak ingin mengambil kolom dengan file data besar, karena melakukannya akan memperlambat performa aplikasi Anda.
Anda dapat menyiapkan aksesor terpisah di mana aksesor pertama berisi semua kolom kecuali yang memiliki data besar, dan mengambil data dari kolom ini secara otomatis; aksesor pertama adalah aksesor otomatis. Aksesor kedua hanya mengambil kolom yang menyimpan data besar, tetapi tidak mengambil data dari kolom ini secara otomatis. Anda dapat memperbarui metode lain atau mengambil data besar sesuai permintaan.
Accessor 0 adalah aksesor otomatis; ini mengambil semua kolom kecuali kolom dengan data besar.
Aksesor 1 bukan aksesor otomatis; ini mengambil kolom dengan data besar.
Gunakan argumen otomatis untuk menentukan apakah aksesor adalah aksesor otomatis.
Beberapa kolom ISequentialStream. Dalam skenario ini, Anda memiliki lebih dari satu kolom yang menyimpan
ISequentialStreamdata. Namun, setiap aksesor terbatas pada satuISequentialStreamaliran data. Untuk mengatasi masalah ini, siapkan beberapa aksesor, masing-masing memiliki satuISequentialStreampenunjuk.
Anda biasanya membuat aksesor menggunakan makro BEGIN_ACCESSOR dan END_ACCESSOR . Anda juga dapat menggunakan atribut db_accessor . (Aksesor dijelaskan lebih lanjut di Rekaman Pengguna.) Makro atau atribut menentukan apakah aksesor adalah aksesor otomatis atau non-otomatis:
Di aksesor otomatis, pindahkan metode seperti
MoveFirst, ,MoveLastMoveNext, danMovePrevambil data untuk semua kolom yang ditentukan secara otomatis. Aksesor 0 harus menjadi aksesor otomatis.Dalam aksesor non-otomatis, pengambilan tidak terjadi sampai Anda secara eksplisit memanggil metode seperti
Update, ,InsertFetch, atauDelete. Dalam skenario yang dijelaskan di atas, Anda mungkin tidak ingin mengambil semua kolom pada setiap gerakan. Anda dapat menempatkan satu atau beberapa kolom di aksesor terpisah dan menjadikannya aksesor non-otomatis, seperti yang ditunjukkan di bawah ini.
Contoh berikut menggunakan beberapa aksesor untuk membaca dan menulis ke tabel pekerjaan database pub SQL Server menggunakan beberapa aksesor. Contoh ini adalah penggunaan yang paling umum dari beberapa aksesor; lihat skenario "beberapa set baris baca/tulis" di atas.
Kelas rekaman pengguna adalah sebagai berikut. Ini menyiapkan dua aksesor: aksesor 0 hanya berisi kolom kunci utama (ID) dan aksesor 1 berisi kolom lain.
class CJobs
{
public:
enum {
sizeOfDescription = 51
};
short nID;
char szDescription[ sizeOfDescription ];
short nMinLvl;
short nMaxLvl;
DWORD dwID;
DWORD dwDescription;
DWORD dwMinLvl;
DWORD dwMaxLvl;
BEGIN_ACCESSOR_MAP(CJobs, 2)
// Accessor 0 is the automatic accessor
BEGIN_ACCESSOR(0, true)
COLUMN_ENTRY_STATUS(1, nID, dwID)
END_ACCESSOR()
// Accessor 1 is the non-automatic accessor
BEGIN_ACCESSOR(1, true)
COLUMN_ENTRY_STATUS(2, szDescription, dwDescription)
COLUMN_ENTRY_STATUS(3, nMinLvl, dwMinLvl)
COLUMN_ENTRY_STATUS(4, nMaxLvl, dwMaxLvl)
END_ACCESSOR()
END_ACCESSOR_MAP()
};
Kode utamanya adalah sebagai berikut. Memanggil MoveNext secara otomatis mengambil data dari ID kolom kunci utama menggunakan aksesor 0. Perhatikan bagaimana metode di Insert dekat akhir menggunakan aksesor 1 untuk menghindari penulisan ke kolom kunci utama.
int main(int argc, char* argv[])
{
// Initialize COM
::CoInitialize(NULL);
// Create instances of the data source and session
CDataSource source;
CSession session;
HRESULT hr = S_OK;
// Set initialization properties
CDBPropSet dbinit(DBPROPSET_DBINIT);
dbinit.AddProperty(DBPROP_AUTH_USERID, OLESTR("my_user_id"));
dbinit.AddProperty(DBPROP_INIT_CATALOG, OLESTR("pubs"));
dbinit.AddProperty(DBPROP_INIT_DATASOURCE, OLESTR("(local)"));
hr = source.Open("SQLOLEDB.1", &dbinit);
if (hr == S_OK)
{
hr = session.Open(source);
if (hr == S_OK)
{
// Ready to fetch/access data
CTable<CAccessor<CJobs>> jobs;
// Set properties for making the rowset a read/write cursor
CDBPropSet dbRowset(DBPROPSET_ROWSET);
dbRowset.AddProperty(DBPROP_CANFETCHBACKWARDS, true);
dbRowset.AddProperty(DBPROP_CANSCROLLBACKWARDS, true);
dbRowset.AddProperty(DBPROP_IRowsetChange, true);
dbRowset.AddProperty(DBPROP_UPDATABILITY,
DBPROPVAL_UP_INSERT | DBPROPVAL_UP_CHANGE |
DBPROPVAL_UP_DELETE);
hr = jobs.Open(session, "jobs", &dbRowset);
if (hr == S_OK)
{
// Calling MoveNext automatically retrieves ID
// (using accessor 0)
while(jobs.MoveNext() == S_OK)
printf_s("Description = %s\n", jobs.szDescription);
hr = jobs.MoveFirst();
if (hr == S_OK)
{
jobs.nID = 25;
strcpy_s(&jobs.szDescription[0],
jobs.sizeOfDescription,
"Developer");
jobs.nMinLvl = 10;
jobs.nMaxLvl = 20;
jobs.dwDescription = DBSTATUS_S_OK;
jobs.dwID = DBSTATUS_S_OK;
jobs.dwMaxLvl = DBSTATUS_S_OK;
jobs.dwMinLvl = DBSTATUS_S_OK;
// Insert method uses accessor 1
// (to avoid writing to the primary key column)
hr = jobs.Insert(1);
}
jobs.Close();
}
session.Close();
}
source.Close();
}
// Uninitialize COM
::CoUninitialize();
return 0;
}