Usando vários assessores em um conjunto de linhas
Há três cenários básicos de precisar usar vários assessores:
Vários conjuntos de linhas de leitura/gravação. Nesse cenário, você tem uma tabela com uma chave primária.Você deseja ser capaz de ler todas as colunas na linha, incluindo a chave primária.Você também deseja ser capaz de gravar dados em todas as colunas, exceto a chave primária (porque você não pode gravar a coluna chave primária).Nesse caso, você definir dois assessores:
O acessador 0 contém todas as colunas.
Assessor 1 contém todas as colunas, exceto a chave primária.
Desempenho. Nesse cenário, uma ou mais colunas contêm uma grande quantidade de dados, por exemplo, elementos gráficos, som ou vídeo arquivos.Toda vez que você mover uma linha, provavelmente não deseja recuperar a coluna com o arquivo de dados grandes, porque fazer assim seria lento o desempenho do aplicativo.
Você pode definir acessadores separados no qual o acessador primeiro contém todas as colunas, exceto aquele com dados grandes e recupera dados dessas colunas automaticamente; Este é um acessador automático.O acessador segundo recupera somente a coluna que contém dados grandes, mas ela não recupera dados de coluna automaticamente.Você pode ter outros métodos para atualizar ou buscar os dados de grandes demanda.
O acessador 0 é um acessador automático; ele recupera todas as colunas, exceto aquele com dados grandes.
Acessador 1 não é um acessador automático; ele recupera a coluna com dados grandes.
Use o argumento de automática para especificar se o acessador é um acessador automático.
Várias colunas ISequentialStream. Nesse cenário, você tem mais de uma coluna contendo ISequentialStream dados.No entanto, cada acessador é limitado a uma ISequentialStream fluxo de dados.Para resolver esse problema, configure vários assessores, cada uma contendo um ISequentialStream ponteiro.
Você normalmente cria acessadores usando o BEGIN_ACCESSOR e END_ACCESSOR macros.Você também pode usar o db_accessor atributo.(Acessadores são descritos mais em Registros de usuário.) As macros ou o atributo de especificar se um acessador é automático ou um acessador não automático:
Um acessador automático mover métodos como MoveFirst, MoveLast, MoveNext, e MovePrev recuperar dados de colunas especificado automaticamente.O acessador 0 deve ser acessador automático.
Um acessador não automático, a recuperação não ocorre até que você explicitamente chamar um método, como atualização, Inserir, Buscar, ou Excluir.Nas situações descritas acima, você não poderá recuperar todas as colunas em cada movimento.Você pode colocar uma ou mais colunas em um acessador separado e verifique um acessador não automática, como mostrado abaixo.
O exemplo a seguir usa vários assessores para leitura e gravação para a tabela de trabalhos do banco de dados de pubs SQL Server usando vários assessores.Este é o uso mais comum de vários assessores; Consulte o cenário "vários conjuntos de leitura/gravação" acima.
A classe de registro de usuário é o seguinte:Define dois acessadores: acessador 0 contém somente a coluna chave primária (ID) e assessor 1 contém outras colunas.
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()
};
O código principal é o seguinte:Chamando MoveNext recupera automaticamente os dados da ID de coluna de chave primária usando o acessador 0.Observe como o Inserir método perto o acessador final usa 1 para evitar a coluna de chave primária.
int main(int argc, char* argv[])
{
// Initalize 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;
}