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.