Compartilhar via


Conjunto de registros: recuperando registros em massa (ODBC)

Este tópico aplica-se às classes ODBC do MFC.

A classe CRecordset permite busca de linha em massa, o que significa que vários registros podem ser recuperados ao mesmo tempo durante uma única busca, em vez de recuperar um registro por vez da fonte de dados. Você pode implementar a busca em massa de linhas somente em uma classe CRecordset derivada. O processo de transferência de dados da fonte de dados para o objeto conjunto de registros é chamado de troca de campo de registro em massa (RFX em massa). Observe que, se você não estiver usando a busca de linha em massa em uma classe derivada CRecordset, os dados serão transferidos por meio da RFX (troca de campo de registro). Para obter mais informações, confira Troca de Campo de Registro (RFX).

Este tópico explica:

Como o CRecordset permite busca em massa de linhas

Antes de abrir o objeto conjunto de registros, você pode definir um tamanho de conjunto de linhas com o SetRowsetSize da função membro. O tamanho do conjunto de linhas especifica quantos registros devem ser recuperados durante uma única busca. Quando a busca em linha em massa é implementada, o tamanho do conjunto de linhas padrão é 25. Se a busca em linha em massa não for implementada, o tamanho do conjunto de linhas permanecerá fixo em 1.

Depois de inicializar o tamanho do conjunto de linhas, chame a função membro Abrir. Aqui você precisa especificar a opção CRecordset::useMultiRowFetch do parâmetro dwOptions para implementar a busca de linha em lote. Além disso, você pode definir a opção CRecordset::userAllocMultiRowBuffers. O mecanismo de troca de campo de registro em massa usa matrizes para armazenar as várias linhas de dados recuperadas durante uma busca. Esses buffers de armazenamento podem ser alocados automaticamente pela estrutura ou manualmente por você. Especificar a opção CRecordset::userAllocMultiRowBuffers significa que você fará a alocação.

A tabela a seguir lista as funções de membro fornecidas por CRecordset para dar suporte à busca em massa de linhas.

Função de membro Descrição
CheckRowsetError Função virtual que manipula todos os erros que ocorrem durante a busca.
DoBulkFieldExchange Implementa a troca de campo de registro em massa. Chamado automaticamente para transferir várias linhas de dados da fonte de dados para o objeto de conjunto de registros.
GetRowsetSize Recupera a configuração atual para o tamanho do conjunto de linhas.
GetRowsFetched Informa quantas linhas foram realmente recuperadas após uma determinada busca. Na maioria dos casos, esse é o tamanho do conjunto de linhas, a menos que um conjunto de linhas incompleto tenha sido buscado.
GetRowStatus Retorna um status de busca para uma linha específica dentro de um conjunto de linhas.
RefreshRowset Atualiza os dados e o status de uma linha específica em um conjunto de linhas.
SetRowsetCursorPosition Move o cursor para uma linha específica dentro de um conjunto de linhas.
SetRowsetSize Função virtual que altera a configuração do tamanho do conjunto de linhas para o valor especificado.

Considerações especiais

Embora a busca em linha em massa seja um ganho de desempenho, determinados recursos operam de forma diferente. Antes de decidir implementar a busca em massa de linhas, considere o seguinte:

  • A estrutura chama automaticamente a função membro DoBulkFieldExchange para transferir dados da fonte de dados para o objeto de registro de dados. No entanto, os dados não são transferidos do conjunto de registros de volta para a fonte de dados. Chamar as funções membro AddNew, Edit, Delete ou Update resulta em uma declaração com falha. Embora CRecordset não forneça atualmente um mecanismo para atualizar linhas de dados em massa, você pode escrever suas próprias funções usando a função API ODBC SQLSetPos. Para obter mais informações sobre SQLSetPos, consulte a Referência do Programador de ODBC.

  • As funções de membro, IsDeleted, IsFieldDirty, IsFieldNull, IsFieldNullable, SetFieldDirty e SetFieldNull não podem ser usadas em conjuntos de registros que implementam a busca em massa de linhas. No entanto, você pode chamar GetRowStatus no lugar de IsDeleted, e GetODBCFieldInfo no lugar de IsFieldNullable.

  • As operações de Move reposicionam o conjunto de registros por conjunto de linhas. Por exemplo, suponha que você abra um conjunto de registros com 100 registros com um tamanho inicial de conjunto de linhas de 10. Open busca das linhas 1 a 10, com o registro atual posicionado na linha 1. Uma chamada para MoveNext busca o próximo conjunto de linhas, não a próxima linha. Esse conjunto de linhas consiste nas linhas 11 a 20, com o registro atual posicionado na linha 11. Observe que MoveNext e Move( 1 ) não são equivalentes quando a busca em massa de linhas é implementada. Move( 1 ) busca o conjunto de linhas que começa na linha 1 do registro atual. Neste exemplo, chamar Move( 1 ) depois de chamar Open busca o conjunto de linhas que consiste nas linhas 2 a 11, com o registro atual posicionado na linha 2. Para obter mais informações, confira a função do membro Mover.

  • Ao contrário da troca de campos de registro, os assistentes não permitem troca de campo de registro em massa. Isso significa que você precisa declarar manualmente seus membros de dados de campo e substituir DoBulkFieldExchange manualmente escrevendo chamadas para as funções RFX em massa. Para obter mais informações, consulte Registrar funções de troca de campos na Referência da biblioteca de classes.

Como implementar uma troca de campos de registro em massa

A troca do campo de registro em massa transfere apenas um conjunto de registros de dados para o objeto de conjunto de registros. As funções RFX em massa usam matrizes para armazenar esses dados, bem como matrizes para armazenar o comprimento de cada item de dados no conjunto de linhas. Em sua definição de classe, você precisa definir seus membros de dados de campo como ponteiros para acessar as matrizes de dados. Além disso, você precisa definir um conjunto de ponteiros para acessar as matrizes de comprimentos. Os membros de dados de parâmetro não devem ser declarados como ponteiros; declarar membros de dados de parâmetro ao usar a troca de campos de registro em massa é o mesmo que declará-los ao usar a troca de campos de registro. O código a seguir mostra um exemplo simples:

class MultiRowSet : public CRecordset
{
public:
   // Field/Param Data
      // field data members
      long* m_rgID;
      LPSTR m_rgName;

      // pointers for the lengths
      // of the field data
      long* m_rgIDLengths;
      long* m_rgNameLengths;

      // input parameter data member
      CString m_strNameParam;

   .
   .
   .
}

Você pode alocar esses buffers de armazenamento manualmente ou fazer com que a estrutura faça a alocação. Para implementar a busca de linhas em massa, você precisa especificar a opção CRecordset::userAllocMultiRowBuffers do parâmetro dwOptions na função de membro Open. Defina os tamanhos das matrizes pelo menos iguais ao tamanho do conjunto de linhas. Se você quiser que a estrutura faça a alocação, inicialize seus ponteiros para NULL. Normalmente, isso é feito no construtor do objeto recordset:

MultiRowSet::MultiRowSet( CDatabase* pDB )
   : CRecordset( pDB )
{
   m_rgID = NULL;
   m_rgName = NULL;
   m_rgIDLengths = NULL;
   m_rgNameLengths = NULL;
   m_strNameParam = "";

   m_nFields = 2;
   m_nParams = 1;

   .
   .
   .
}

Por fim, você precisa substituir a função de membro DoBulkFieldExchange. Para os membros de dados de campo, chame as funções RFX em massa; para qualquer membro de dados de parâmetro, chame as funções RFX. Se você abriu o conjunto de registros passando uma instrução SQL ou procedimento armazenado para Open, a ordem na qual você faz as chamadas RFX em massa precisa corresponder à ordem das colunas no conjunto de registros. Da mesma forma, a ordem das chamadas RFX para parâmetros precisa corresponder à ordem dos parâmetros na instrução SQL ou no procedimento armazenado.

void MultiRowSet::DoBulkFieldExchange( CFieldExchange* pFX )
{
   // call the Bulk RFX functions
   // for field data members
   pFX->SetFieldType( CFieldExchange::outputColumn );
   RFX_Long_Bulk( pFX, _T( "[colRecID]" ),
                  &m_rgID, &m_rgIDLengths );
   RFX_Text_Bulk( pFX, _T( "[colName]" ),
                  &m_rgName, &m_rgNameLengths, 30 );

   // call the RFX functions for
   // for parameter data members
   pFX->SetFieldType( CFieldExchange::inputParam );
   RFX_Text( pFX, "NameParam", m_strNameParam );
}

Observação

Você precisa chamar a função do membro Close antes que sua classe CRecordset derivada saia do escopo. Isso garante que qualquer memória alocada pela estrutura seja liberada. É uma boa prática de programação sempre chamar Closeexplicitamente, independentemente de você ter implementado a busca em massa de linhas.

Para obter mais informações sobre a RFX (troca de campo de registro), consulte Registrar troca de campos: Como o RFX funciona. Para obter mais informações sobre como usar parâmetros, consulte CFieldExchange::SetFieldType e Conjunto de registros: Parametrizando um conjunto de registros (ODBC).

Confira também

Conjunto de registros (ODBC)
CRecordset::m_nFields
CRecordset::m_nParams