Partilhar via


Conjunto de registros: ODBC (Dynamically Binding Data Columns)

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

Os conjuntos de registos gerem colunas de tabela de ligação que são especificadas em tempo de projeto, mas há casos em que pode ser necessário ligar colunas que eram desconhecidas em tempo de projeto. Este tópico explica:

Observação

Este tópico aplica-se a objetos derivados de CRecordset nos quais a busca de linhas em massa não foi implementada. As técnicas descritas geralmente não são recomendadas se você estiver usando a busca de linha em massa. Para obter mais informações sobre a busca de linhas em massa, consulte Recordset: Buscando registros em massa (ODBC).

Quando você pode vincular colunas dinamicamente

Observação

O assistente MFC ODBC Consumer não está disponível no Visual Studio 2019 e em versões posteriores. Você ainda pode criar um consumidor manualmente.

Durante a fase de criação, o MFC Application Wizard ou MFC ODBC Consumer Wizard (de Add Class) cria classes de conjunto de registros com base nas tabelas e colunas conhecidas na sua origem de dados. Os bancos de dados podem mudar entre quando você os projeta e mais tarde, quando seu aplicativo usa essas tabelas e colunas em tempo de execução. Você ou outro usuário pode adicionar ou soltar uma tabela ou adicionar ou soltar colunas de uma tabela na qual o conjunto de registros do seu aplicativo depende. Isso provavelmente não é uma preocupação para todos os aplicativos de acesso a dados, mas se for para o seu, como você pode lidar com as alterações no esquema do banco de dados, além de redesenhar e recompilar? O objetivo deste tópico é responder a essa pergunta.

Este tópico descreve o caso mais comum em que você pode vincular colunas dinamicamente — tendo começado com um conjunto de registros com base em um esquema de banco de dados conhecido, você deseja manipular colunas adicionais em tempo de execução. O tópico supõe ainda que as colunas adicionais estão mapeadas para CString membros de dados de campo, o caso mais comum, embora se forneçam sugestões para ajudá-lo a gerir outros tipos de dados.

Com uma pequena quantidade de código extra, você pode:

Seu conjunto de registros ainda contém membros de dados para as colunas que você conhecia em tempo de design. Ele também contém uma pequena quantidade de código extra que determina dinamicamente se novas colunas foram adicionadas à sua tabela de destino e, em caso afirmativo, vincula essas novas colunas ao armazenamento alocado dinamicamente (em vez de aos membros de dados do conjunto de registros).

Este tópico não abrange outros casos de vinculação dinâmica, como tabelas ou colunas descartadas. Para esses casos, você precisa usar chamadas de API ODBC mais diretamente. Para obter informações, consulte a referência do programador ODBC.

Como vincular colunas dinamicamente

Para vincular colunas dinamicamente, você deve saber (ou ser capaz de determinar) os nomes das colunas adicionais. Você também deve alocar armazenamento para os membros de dados de campo adicionais, especificar seus nomes e tipos e especificar o número de colunas que você está adicionando.

A discussão a seguir menciona dois conjuntos de registros diferentes. O primeiro é o conjunto de registros principal que seleciona registros da tabela de destino. O segundo é um conjunto de registros de coluna especial usado para obter informações sobre as colunas na tabela de destino.

Processo Geral

No nível mais geral, siga estas etapas:

  1. Construa seu objeto principal do conjunto de registros.

    Opcionalmente, passe um ponteiro para um objeto aberto CDatabase ou seja capaz de fornecer informações de conexão para o conjunto de registros de coluna de alguma outra forma.

  2. Execute etapas para adicionar colunas dinamicamente.

    Veja o processo descrito em Adicionando as colunas abaixo.

  3. Abra seu conjunto de registros principal.

    O conjunto de registros seleciona registros e usa a troca de campos de registro (RFX) para vincular as colunas estáticas (aquelas mapeadas para membros de dados de campo do conjunto de registros) e as colunas dinâmicas (mapeadas para armazenamento extra alocado por você).

Adicionando as colunas

A vinculação dinâmica de colunas adicionadas em tempo de execução requer as seguintes etapas:

  1. Determine em tempo de execução quais colunas estão na tabela de destino. Extraia dessas informações uma lista das colunas que foram adicionadas à tabela desde que sua classe de conjunto de registros foi projetada.

    Uma boa abordagem é usar uma classe de conjunto de registros de coluna projetada para consultar a fonte de dados para obter informações de coluna para a tabela de destino (como nome da coluna e tipo de dados).

  2. Fornecer armazenamento para os novos membros de dados de campo. Como sua classe principal do conjunto de registros não tem membros de dados de campo para colunas desconhecidas, você deve fornecer um local para armazenar os nomes, valores de resultado e, possivelmente, informações de tipo de dados (se as colunas forem tipos de dados diferentes).

    Uma abordagem é criar uma ou mais listas dinâmicas, uma para os nomes das novas colunas, outra para seus valores de resultado e uma terceira para seus tipos de dados (se necessário). Estas listas, particularmente a lista de valores, fornecem as informações e o armazenamento necessário para a vinculação. A figura a seguir ilustra a construção das listas.

    Criação de listas de colunas para vincular dinamicamente.
    Criando listas de colunas para vincular dinamicamente

  3. Adicione uma chamada de função RFX na função do seu recordset principal para cada coluna adicionada. Essas chamadas RFX realizam a tarefa de obter um registo, incluindo as colunas adicionais, e de vincular as colunas aos membros do conjunto de dados ou ao armazenamento dinamicamente fornecido para eles.

    Uma abordagem é adicionar um loop à função do DoFieldExchange conjunto de registros principal que percorre sua lista de novas colunas, chamando a função RFX apropriada para cada coluna da lista. Em cada chamada RFX, passe um nome de coluna da lista de nomes de coluna e um local de armazenamento no membro correspondente da lista de valores de resultado.

Listas de Colunas

As quatro listas com as quais você precisa trabalhar são mostradas na tabela a seguir.

Lista Descrição
Colunas da tabela atual (Lista 1 na ilustração) Uma lista das colunas atualmente presentes na tabela da fonte de dados. Esta lista pode corresponder à lista de colunas atualmente vinculadas no seu conjunto de registros.
Colunas de Conjunto de Registos Ligados (Lista 2 na ilustração) Uma lista das colunas encadernadas no conjunto de registros. Estas colunas já têm instruções RFX na sua função DoFieldExchange.
Colunas-para-vincular-dinamicamente (Lista 3 na ilustração) Uma lista de colunas na tabela, mas não no seu conjunto de dados. Estas são as colunas que você deseja vincular dinamicamente.
Valores de coluna dinâmicos (Lista 4 na ilustração) Uma lista contendo armazenamento para os valores recuperados das colunas que você vincula dinamicamente. Os elementos desta lista correspondem aos de Colunas-para-Ligar-Dinamicamente, um a um.

Construindo suas listas

Com uma estratégia geral em mente, você pode recorrer aos detalhes. Os procedimentos no restante deste tópico mostram como criar as listas mostradas em Listas de Colunas. Os procedimentos orientam-no através de:

Determinando quais colunas da tabela não estão no conjunto de registros

Crie uma lista (Bound-Recordset-Columns, como na Lista 2 da ilustração) que contenha uma lista das colunas já vinculadas no seu conjunto de registos principal. Em seguida, crie uma lista (Columns-to-Bind-Dynamically, derivada de Current-Table-Columns e Bound-Recordset-Columns) que contenha nomes de colunas que estão na tabela na fonte de dados, mas não no seu conjunto de registros principal.

Para determinar os nomes das colunas que não estão no conjunto de registros (Columns-to-Bind-Dynamically)
  1. Crie uma lista (Bound-Recordset-Columns) das colunas já associadas ao seu conjunto de registos principal.

    Uma abordagem é criar Bound-Recordset-Columns na fase de conceção. Pode examinar visualmente as chamadas de função RFX na função do DoFieldExchange recordset para obter esses nomes. Em seguida, configure sua lista como uma matriz inicializada com os nomes.

    Por exemplo, a ilustração mostra Bound-Recordset-Columns (Lista 2) com três elementos. Bound-Recordset-Columns falta a coluna Telefone apresentada em Current-Table-Columns (Lista 1).

  2. Compare Current-Table-Columns e Bound-Recordset-Columns para criar uma lista (Columns-to-Bind-Dynamically) das colunas ainda não vinculadas no seu conjunto de dados principal.

    Uma abordagem é percorrer a lista de colunas na tabela em tempo de execução (Current-Table-Columns) e sua lista de colunas já encadernadas no conjunto de registros (Bound-Recordset-Columns) em paralelo. Insira em Colunas-para-Bind-Dynamically os nomes no Current-Table-Columns que não estão em Bound-Recordset-Columns.

    Por exemplo, a ilustração mostra Columns-to-Bind-Dynamically (Lista 3) com um elemento: a coluna Telefone encontrada em Current-Table-Columns (Lista 1), mas não em Bound-Recordset-Columns (Lista 2).

  3. Crie uma lista deColumn-Values dinâmicos (como na Lista 4 na ilustração) na qual armazenar os valores de dados correspondentes a cada nome de coluna guardado na sua lista de colunas para associação dinâmica (Colunas-para-Bind-Dynamically).

    Os elementos dessa lista desempenham o papel de novos membros de dados de campo do conjunto de registros. Eles são os locais de armazenamento aos quais as colunas dinâmicas estão vinculadas. Para obter descrições das listas, consulte Listas de colunas.

Fornecendo armazenamento para as novas colunas

Em seguida, configure locais de armazenamento para que as colunas sejam vinculadas dinamicamente. A ideia é fornecer um elemento de lista no qual armazenar o valor de cada coluna. Esses locais de armazenamento são paralelos às variáveis de membro do conjunto de registros, que armazenam as colunas normalmente vinculadas.

Para fornecer armazenamento dinâmico para novas colunas (Dinâmico-Column-Values)

  1. Crie Valores-de-Coluna-Dinâmicos, paralelo a Colunas-a-Ligar-Dinamicamente, para conter o valor dos dados em cada coluna.

    Por exemplo, a ilustração mostra Dynamic-Column-Values (Lista 4) com um elemento: um CString objeto contendo o número de telefone real para o registro atual: "555-1212".

    No caso mais comum, Dynamic-Column-Values tem elementos do tipo CString. Se você estiver lidando com colunas de tipos de dados variados, precisará de uma lista que possa conter elementos de vários tipos.

O resultado dos procedimentos anteriores são duas listas principais: Columns-to-Bind-Dynamically, que contém os nomes das colunas, e Dynamic-Column-Values, que contém os valores nas colunas para o registo atual.

Sugestão

Se as novas colunas não forem todas do mesmo tipo de dados, talvez você queira uma lista paralela extra contendo itens que, de alguma forma, definam o tipo de cada elemento correspondente na lista de colunas. (Você pode usar os valores AFX_RFX_BOOL, AFX_RFX_BYTE e assim por diante, para isso, se desejar. Essas constantes são definidas em AFXDB.H.) Escolha um tipo de lista com base em como você representa os tipos de dados de coluna.

Adicionando chamadas RFX para vincular as colunas

Finalmente, providencie para que a ligação dinâmica ocorra colocando chamadas RFX para as novas colunas em sua DoFieldExchange função.

Para adicionar chamadas RFX de forma dinâmica para novas colunas
  1. Na função de membro do DoFieldExchange seu conjunto de registros principal, adicione código que percorre sua lista de novas colunas (Colunas-para-Bind-Dynamically). Em cada loop, extraia um nome de coluna de Columns-to-Bind-Dynamically e um valor de resultado para a coluna de Dynamic-Column-Values. Passe esses itens para uma chamada de função RFX apropriada para o tipo de dados da coluna. Para obter descrições das listas, consulte Listas de colunas.

No caso comum, em suas RFX_Text chamadas de função você extrai CString objetos das listas, como nas seguintes linhas de código, onde Columns-to-Bind-Dynamically é um CStringList chamado m_listName e Dynamic-Column-Values é um CStringList chamado m_listValue:

RFX_Text( pFX,
            m_listName.GetNext( posName ),
            m_listValue.GetNext( posValue ));

Para obter mais informações sobre funções RFX, consulte Macros e Globais na Referência da Biblioteca de Classes.

Sugestão

Se as novas colunas forem tipos de dados diferentes, use uma instrução switch em seu loop para chamar a função RFX apropriada para cada tipo.

Quando a estrutura chama DoFieldExchange durante o Open processo para vincular colunas ao conjunto de registros, a RFX chama as colunas estáticas para vincular essas colunas. Em seguida, seu loop chama repetidamente funções RFX para as colunas dinâmicas.

Ver também

Conjunto de registros (ODBC)
Conjunto de registros: Trabalhando com itens de dados grandes (ODBC)