Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Observação
O DAO é usado com bancos de dados do Access e é suportado pelo Office 2013. DAO 3.6 é a versão final, e é considerado obsoleto. O ambiente e os assistentes do Visual C++ não oferecem suporte a DAO (embora as classes DAO estejam incluídas e você ainda possa usá-las). A Microsoft recomenda que você use modelos OLE DB ou ODBC e MFC para novos projetos. Você só deve usar o DAO na manutenção de aplicativos existentes.
Esta nota técnica descreve o mecanismo de troca de campo de registro DAO (DFX). Para ajudar a entender o que está a acontecer nas rotinas de DFX, a função DFX_Text será explicada como exemplo em detalhes. Como fonte adicional de informações para esta nota técnica, você pode examinar o código para as outras funções DFX individuais. Você provavelmente não precisará de uma rotina DFX personalizada com tanta frequência quanto você pode precisar de uma rotina RFX personalizada (usada com classes de banco de dados ODBC).
Esta nota técnica contém:
Visão geral do DFX
Exemplos de uso do DAO Record Field Exchange e da vinculação dinâmica
Visão geral do DFX
O mecanismo de troca de campo de registro DAO (DFX) é usado para simplificar o procedimento de recuperação e atualização de dados ao usar a CDaoRecordset classe. O processo é simplificado usando membros de dados da CDaoRecordset classe. Derivando de CDaoRecordset, pode adicionar membros de dados à classe derivada que representa cada campo numa tabela ou consulta. Esse mecanismo de "vinculação estática" é simples, mas pode não ser o método de busca/atualização de dados preferido para todos os aplicativos. O DFX recupera todos os campos vinculados sempre que o registo atual é alterado. Se você estiver desenvolvendo um aplicativo sensível ao desempenho que não exija buscar todos os campos quando a moeda for alterada, a "vinculação dinâmica" via CDaoRecordset::GetFieldValue e CDaoRecordset::SetFieldValue pode ser o método de acesso a dados preferido.
Observação
DFX e ligação dinâmica não são mutuamente exclusivos, portanto, um uso híbrido de ligação estática e dinâmica pode ser usado.
Exemplo 1 — Uso apenas do DAO Record Field Exchange
(assume — CDaoRecordset classe derivada CMySet já aberta)
// Add a new record to the customers table
myset.AddNew();
myset.m_strCustID = _T("MSFT");
myset.m_strCustName = _T("Microsoft");
myset.Update();
Exemplo 2 — Utilização apenas da ligação dinâmica
(assume-se o uso da CDaoRecordset classe, rs, e já está aberto)
// Add a new record to the customers table
COleVariant varFieldValue1 (_T("MSFT"),
VT_BSTRT);
//Note: VT_BSTRT flags string type as ANSI,
instead of UNICODE default
COleVariant varFieldValue2 (_T("Microsoft"),
VT_BSTRT);
rs.AddNew();
rs.SetFieldValue(_T("Customer_ID"),
varFieldValue1);
rs.SetFieldValue(_T("Customer_Name"),
varFieldValue2);
rs.Update();
Exemplo 3 — Uso do DAO Record Field Exchange e vinculação dinâmica
(pressupõe a navegação de dados de funcionários com CDaoRecordsetclasse empderivada)
// Get the employee's data so that it can be displayed
emp.MoveNext();
// If user wants to see employee's photograph,
// fetch it
COleVariant varPhoto;
if (bSeePicture)
emp.GetFieldValue(_T("photo"),
varPhoto);
// Display the data
PopUpEmployeeData(emp.m_strFirstName,
emp.m_strLastName,
varPhoto);
Como funciona o DFX
O mecanismo DFX funciona de forma semelhante ao mecanismo de troca de campo de registro (RFX) usado pelas classes ODBC MFC. Os princípios de DFX e RFX são os mesmos, mas existem inúmeras diferenças internas. O design das funções DFX foi tal que praticamente todo o código é compartilhado pelas rotinas DFX individuais. Ao mais alto nível, o DFX faz apenas algumas coisas.
DFX constrói a cláusula SQL SELECT e a cláusula SQL PARAMETERS , se necessário.
DFX constrói a estrutura de ligação usada pela função do
GetRowsDAO (mais sobre isso mais tarde).O DFX gerencia o buffer de dados usado para detetar campos sujos (se o buffer duplo estiver sendo usado)
O DFX gerencia as matrizes de status NULL e DIRTY e define valores, se necessário, nas atualizações.
No coração do mecanismo DFX está a CDaoRecordset função da DoFieldExchange classe derivada. Esta função envia chamadas para as funções DFX individuais de um tipo de operação apropriado. Antes de chamar DoFieldExchange as funções MFC internas, defina o tipo de operação. A lista a seguir mostra os vários tipos de operação e uma breve descrição.
| Funcionamento | Descrição |
|---|---|
AddToParameterList |
Constrói a cláusula PARAMETERS |
AddToSelectList |
Constrói a cláusula SELECT |
BindField |
Configura a estrutura de vinculação |
BindParam |
Define valores de parâmetros |
Fixup |
Atribui o estado NULL |
AllocCache |
Aloca cache para verificação suja |
StoreField |
Salva o registro atual no cache |
LoadField |
Restaura o cache para valores de membro |
FreeCache |
Libera a cache |
SetFieldNull |
Define o status do campo e valor como NULL |
MarkForAddNew |
Marca campos sujos, se não PSEUDO NULL |
MarkForEdit |
Marca campos sujos se não corresponderem ao cache |
SetDirtyField |
Define valores de campo marcados como sujos |
Na próxima seção, cada operação será explicada com mais detalhes para DFX_Text.
Para entender o recurso mais importante do processo de troca de campo de registro DAO, é essencial saber que ele utiliza a função GetRows do objeto CDaoRecordset. A função DAO GetRows pode funcionar de várias maneiras. A presente nota técnica descreverá apenas sucintamente GetRows , uma vez que está fora do âmbito da presente nota técnica.
DAO GetRows pode funcionar de várias maneiras.
Ele pode buscar vários registros e vários campos de dados ao mesmo tempo. Isto permite um acesso mais rápido aos dados, com a complicação de gerir uma grande estrutura de dados e os offsets apropriados para cada campo e para cada registo de dados na estrutura. MFC não tira partido deste mecanismo de busca de múltiplos registos.
Outra maneira
GetRowsde funcionar é permitir que os programadores especifiquem endereços vinculativos para os dados recuperados de cada campo para um registro de dados.O DAO também fará uma "chamada de retorno" ao chamador para colunas de comprimento variável, a fim de permitir que ele aloque memória. Este segundo recurso tem o benefício de minimizar o número de cópias de dados, bem como permitir o armazenamento direto de dados em membros de uma classe (a
CDaoRecordsetclasse derivada). Este segundo mecanismo é o método que MFC usa para vincular a membros de dados emCDaoRecordsetclasses derivadas.
O que sua rotina DFX personalizada faz
É evidente a partir desta discussão que a operação mais importante implementada em qualquer função DFX deve ser a capacidade de configurar as estruturas de dados necessárias para chamar GetRowscom êxito . Há uma série de outras operações que uma função DFX também deve suportar, mas nenhuma tão importante ou complexa quanto se preparar corretamente para a GetRows chamada.
O uso do DFX está descrito na documentação on-line. Essencialmente, há dois requisitos. Primeiro, os membros devem ser adicionados à classe derivada CDaoRecordset para cada campo vinculado e parâmetro. Depois disso, CDaoRecordset::DoFieldExchange deve ser substituído. Observe que o tipo de dados do membro é importante. Deve corresponder aos dados do campo na base de dados ou, pelo menos, ser convertível para esse tipo. Por exemplo, um campo numérico numa base de dados, como um inteiro longo, pode sempre ser convertido em texto e associado a um CString membro, mas um campo de texto numa base de dados nem sempre pode ser convertido numa representação numérica, como um inteiro longo, e associado a um membro inteiro longo. DAO e o mecanismo de banco de dados Microsoft Jet são responsáveis pela conversão (em vez de MFC).
Detalhes da DFX_Text
Como mencionado anteriormente, a melhor maneira de explicar como o DFX funciona é trabalhar através de um exemplo. Para este efeito, passar pelos aspectos internos do DFX_Text deve ser eficaz para ajudar a proporcionar pelo menos uma compreensão básica do DFX.
AddToParameterListEsta operação cria a cláusula SQL PARAMETERS ("
Parameters <param name>, <param type> ... ;") exigida pelo Jet. Cada parâmetro é nomeado e digitado (conforme especificado na chamada RFX). Consulte a funçãoCDaoFieldExchange::AppendParamTypepara ver os nomes dos tipos individuais. No caso doDFX_Text, o tipo utilizado é texto.AddToSelectListCria a cláusula SQL SELECT . Isso é bastante simples, pois o nome da coluna especificado pela chamada DFX é simplesmente acrescentado ("
SELECT <column name>, ...").BindFieldA mais complexa das operações. Como mencionado anteriormente, é aqui que a estrutura de vinculação DAO usada por
GetRowsé configurada. Como você pode ver a partir do código nosDFX_Texttipos de informações na estrutura incluem o tipo DAO usado (DAO_CHAR ou DAO_WCHAR no caso deDFX_Text). Além disso, o tipo de vinculação usado também é configurado. Numa seção anterior,GetRowsfoi descrito apenas brevemente, mas foi suficiente para explicar que o tipo de vinculação usado pelo MFC é sempre a vinculação de endereço direto (DAOBINDING_DIRECT). Além disso, para a vinculação de colunas com comprimento variável (comoDFX_Text), é utilizada a vinculação de retorno de chamada para que o MFC possa controlar a alocação de memória e especificar um endereço com o comprimento correto. O que isso significa é que o MFC sempre pode dizer ao DAO "onde" colocar os dados, permitindo assim a ligação direta às variáveis membros. O resto da estrutura de vinculação é preenchido com coisas como o endereço da função de retorno de chamada de alocação de memória e o tipo de vinculação de coluna (vinculação por nome de coluna).BindParamEsta é uma operação simples que chama
SetParamValuecom o valor do parâmetro especificado no membro de parâmetros.FixupPreenche o status NULL para cada campo.
SetFieldNullEsta operação marca apenas o status de cada campo como NULL e define o valor da variável membro como PSEUDO_NULL.
SetDirtyFieldChamadas
SetFieldValuepara cada campo marcado sujo.
Todas as operações restantes lidam apenas com o uso do cache de dados. O cache de dados é um buffer extra dos dados no registro atual que é usado para tornar certas coisas mais simples. Por exemplo, os campos "sujos" podem ser detetados automaticamente. Conforme descrito na documentação on-line, ele pode ser desligado completamente ou no nível de campo. A implementação do buffer utiliza um mapa. Este mapa é utilizado para associar cópias dos dados, alocadas dinamicamente, ao endereço do campo "vinculado" (ou membro de dados derivado CDaoRecordset).
AllocCacheAloca dinamicamente o valor do campo armazenado em cache e o adiciona ao mapa.
FreeCacheExclui o valor do campo armazenado em cache e o remove do mapa.
StoreFieldCopia o valor do campo atual para o cache de dados.
LoadFieldCopia o valor armazenado em cache para o membro de campo.
MarkForAddNewVerifica se o valor do campo atual é não-NULL e o marca sujo, se necessário.
MarkForEditCompara o valor do campo atual com o cache de dados e marca sujo, se necessário.
Sugestão
Modele suas rotinas DFX personalizadas nas rotinas DFX existentes para tipos de dados padrão.