Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Existují tři základní scénáře, ve kterých potřebujete použít více přístupových objektů:
Více sad řádků pro čtení a zápis V tomto scénáři máte tabulku s primárním klíčem. Chcete mít možnost číst všechny sloupce v řádku, včetně primárního klíče. Chcete také mít možnost zapisovat data do všech sloupců kromě primárního klíče (protože do sloupce primárního klíče nemůžete zapisovat). V tomto případě nastavíte dva přístupové objekty:
Příslušenství 0 obsahuje všechny sloupce.
Přistupovací objekt 1 obsahuje všechny sloupce kromě primárního klíče.
Výkon. V tomto scénáři má jeden nebo více sloupců velké množství dat, například grafiku, zvuk nebo videosoubory. Pokaždé, když přejdete na řádek, pravděpodobně nechcete načíst sloupec s velkým datovým souborem, protože by to zpomalilo výkon vaší aplikace.
Můžete nastavit samostatné přístupové objekty, ve kterých první přístupový objekt obsahuje všechny sloupce s výjimkou sloupců s velkými daty a načítá data z těchto sloupců automaticky; prvním příslušenstvím je automatický přístup. Druhý přístup načte pouze sloupec, který obsahuje velká data, ale nenačítá data z tohoto sloupce automaticky. Můžete mít další metody, které aktualizují nebo načítají velká data na vyžádání.
Příslušenství 0 je automatický příslušenství; načte všechny sloupce s výjimkou sloupců s velkými daty.
Příslušenství 1 není automatickým příslušenstvím; načte sloupec s velkými daty.
Pomocí automatického argumentu určete, zda je příslušenstvím automatického přístupového objektu.
Více sloupců ISequentialStream V tomto scénáři máte více než jeden sloupec, který obsahuje
ISequentialStreamdata. Každý přístup je však omezen na jedenISequentialStreamdatový proud. Chcete-li tento problém vyřešit, nastavte několik přístupových objektů, z nichž každý má jedenISequentialStreamukazatel.
Obvykle vytváříte přístupové objekty pomocí BEGIN_ACCESSOR a END_ACCESSOR maker. Můžete také použít atribut db_accessor . (Přístupové objekty jsou podrobněji popsány v tématu Záznamy uživatelů.) Makra nebo atribut určují, jestli je příslušenství automatické nebo neautomatické přístupové objekty:
V automatickém přístupové objektu můžete automaticky přesouvat metody, jako
MoveFirstje ,MoveLastMoveNext, aMovePrevnačítat data pro všechny zadané sloupce. Příslušenství 0 by mělo být automatickým příslušenstvím.V neautomatické přístupové objektu se načítání neprojeví, dokud explicitně nezavoláte metodu, jako
Updateje ,Insert,FetchneboDelete. Ve scénářích popsaných výše možná nebudete chtít načíst všechny sloupce při každém přesunu. Jeden nebo více sloupců můžete umístit do samostatného přístupového objektu a nastavit ho jako neautomatické příslušenství, jak je znázorněno níže.
Následující příklad používá více přístupových objektů ke čtení a zápisu do tabulky úloh databáze pubs SQL Serveru pomocí více přístupových objektů. Tento příklad je nejběžnějším použitím více přístupových objektů; viz výše uvedený scénář více sad řádků pro čtení a zápis.
Třída záznamu uživatele je následující. Nastaví dva přístupové objekty: přistupovací objekt 0 obsahuje pouze sloupec primárního klíče (ID) a příslušenství 1 obsahuje další sloupce.
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()
};
Hlavní kód je následující. Volání MoveNext automaticky načte data z ID sloupce primárního klíče pomocí přístupového objektu 0. Všimněte si, jak Insert metoda blízko konce používá přístupové objekty 1, aby se zabránilo zápisu do sloupce primárního klíče.
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;
}