Nesse artigo vou mostrar como criar um relacionamento Master/Detail utilizando o recurso DataSetField do ClientDataSet.

Para podermos criar no Delphi uma relação Master/Detail em uma única estrutura de memória, devemos utilizar datasets aninhados, ou seja, o resultset traz em um dataset os TFields da tabela master e um TField especial chamado TDataSetField, que representará a tabela detail.

Para acessarmos o conteúdo de um TDataSetField, devemos usar a propriedade DataSetField de um componente dataset (no nosso caso, é o ClientDataSet).

Mostrarei, através de uma aplicação simples, como fazer esse relacionamento utilizando os recursos do dbExpress e do ClientDataSet.

Vamos à prática: utilizarei o banco EMPLOYEE do Firebird, que está no caminho: C:\ProgramFiles\Firebird\Firebird_2_5\examples\empbuild\EMPLOYEE.FDB

Crie uma aplicação nova: File > New > VCL FormApplication.

Adicione os seguintes componentes:

  • TSQLConnection (configura a conexão com o banco EMPLOYEE)
    Name:sqlEmployee
  • TSQLQuery
    Name: qryClientes(será o MASTER)
    SQL: select * fromCUSTOMER
    SqlConnection: sqlEmployee
  • TSQLQuery
    Name: qryVendas(seráos DETAILS)
    SQL: select * from SALESwhere CUST_NO = :CUST_NO
    SqlConnection: sqlEmployee
    Params: Configure o parâmetro CUST_NO:DataType = ftInteger e ParamType = ptInput

Nota: O nome do parâmetro deve ser igual ao nome do campo da PK na tabela Master.

Para configurar o relacionamento master/detail em apenas uma estrutura de memória vamos adicionar:

  • um TDataSetProvider apontando para a qryClientes (MASTER),
  • um TClientDataset apontando para oTDataSetProvider e
  • um TDataSource apontando para a qryClientes.

Assim, as configurações ficarão da seguinte forma:

  • TDataSetProvider
    Name: dspMaster
    DataSet: qryClientes
  • TClientDataset
    Name: cdsClientes
    ProviderName: dspMaster
  • TDataSource
    Name: dtsMaster
    DataSet: qryClientes

Nota: Acesse a propriedade DataSource da qryVendas e aponte para dtsMaster.

Neste momento já possuímos a estrutura master/detail montada. Adicionando os TFields no cdsClientes podemos ver os campos da qryClientes e um campo do tipo TDataSetFiel, que representa os dados da qryVendas.

Para testarmos esse relacionamento adicione os seguintes componentes:

  • TDataSource
    Name: dtsClientes
    DataSet: cdsClientes
  • TClientDataset
    Name: cdsVendas
    ProviderName: dspMaster
    DataSetField: cdsClientesqryVendas
    Nota: Adicione os TFields no cdsVendas.
  • TDataSource
    Name: dtsVendas
    DataSet: cdsVendas
    Nota: Para que o DataField qryVendas fique visível apenas no TDBGrid deVendas, deixe esse campo invisível no cdsClientes.
  • TDBGRID (Master)
    Name: dbgClientes
    DataSource: dtsClientes
  • TDBGRID (Detail)
    Name: dbgVendas
    DataSource: dtsVendas

Se tudo foi feito corretamente é só abrir o cdsClientes, rodar a aplicação e conferir o dbgClientes exibindo os dados do cliente e o dbgVendas exibindo suas respectivas vendas.

Note que se forem alterados dados do cliente e/ou de suas vendas, apenas um ApplyUpdates é necessário para enviar em um único datapacket as alterações para o DataSetProvider. Isso é possível porque o DataSetProvider tem a capacidade de distribuir essas alterações entre as querys (qryClientes e a qryVendas) atualizando assim as duas tabelas.

Pronto! Uma forma prática e muito útil principalmente para aplicações client/Server de se criar um relacionamento Master/Detail.