Mestre/Detalhe amp; Commit?
09/06/2008
0
Eu estou acostumado a trabalhar com relacionamento Mestre/Detalhe, porem encontrei um problema que até agora não consegui resolver.
Uso Delphi 2007, Firebird 2.0 com MDO e aplicação com jalenas MDI.
A bronca maior é o fato de eu [b:7454fe04fa]não [/b:7454fe04fa]estar utilizando o [b:7454fe04fa]CommitRetaining [/b:7454fe04fa]como de costume.
Minhas tabelas:
[b:7454fe04fa]Produtos(Cod,Descricao,Modelo)
Produtos_Acessorios(Cod,Qtde,Cod_Produto,Cod_Acessorio)
Acessorios(Cod,Descricao,Valor)[/b:7454fe04fa]
Cada produto é composto por N acessórios, no qual o preço final será composto pela soma de acessoriosXquantidade de cada um.
Antes eu sempre aplicava um Post/CommitRetaining no cadastro do produto para efetivar os dados na tabela, para após isso eu incluir os Acessórios no Grid que é exibido dentro do form de cadastro do Produto.
Agora, quando eu abro o form de cadastro eu tenho uma transação e esta só é finalizada atraves de Commit, eu estou tentando adicionar os acessorios com essa transação aberta, pois caso seja cancelado, nada fique registrado, por exemplo um produto sem acessorios.
Minha dúvida é: como manter essa transação mestre aberta (mesmo sem ter gravado o registro mestre) e incluir dados na tabela detalhe e exibi-los no grid atualizando a cada novo acessorio incluido/excluido, e efetivar todas essas operações somente depois do commit?
abraços
Eniorm
Posts
10/06/2008
Brunodsr
Qndo vc abre uma transação no banco de dados, ele reserva um espaço p/ vc fazer o que quiser: deletar registros, incluir novos, alterar e tudo o mais.
Essa transação será fechada apenas quando vc confirmar os seus comandos ou cancelá-los (commit e rollback). Até lá, os registros modificados ficarão locados ou não com vc (snapshot, readcommited etc).
O commit retaining é uma forma de confirmar as alterações no banco e manter a mesma transação aberta. É tipo uma parcial das suas alterações. É muito usado para commitar grupos de modificações.
No seu caso, vc não precisa comitar a cada post. Isso pode ser feito apenas no final e sem problemas. O master-detail não impede que vc grave cabeçalho e ítens.
Usando o dbexplorer, faça o seguinte:
1. Abra uma transação:
2. Insira os dados do cabeçalho;
3. Insira os dados dos ítens do cabeçalho;
4. Cancele (rollback).
Verifique que os dados não foram gravados.
Espero ter ajudado.
10/06/2008
Eniorm
ou seja, para cada item que eu adiciono eu tenho que exibir no dbgrid
na query desse grid eu uso o SQL trazendo dados das duas tabelas relacionadas e de acordo com o cod do mestre
abraços
10/06/2008
Brunodsr
Faça o seguinte teste.. Daí vc ver na prática o que eu to falando.
1. Abra um form zerado;
2. Inicie a transacao no momento em que ele for criado;
3. Coloque uns 5 ´INSERT INTO TABELA´ na sua query;
4. Coloque um botao para executar ele;
5. Ponha um grid na tela e ligue ele a outro dataset que tem um ´SELECT * FROM TABELA´;
6. Coloque outro botao para executar a segunda query;
7. IMPORTANTE: Se certifique que as duas queries estao na mesma transacao;
8. Coloque um botao na tela;
9. Na programacao dele coloque um rollbackretaining.
Com isso ai vc vai ver que todos os inserts que vc deu sao visualizados no banco (dentro da mesma transacao) e que quando vc cancela elas (rollback), os registros desaparecem.
Use isso para preenher seu cabecalho e itens:
1. Insert na tabela pai;
2. Insert nos filhos; (select no pai para pegar o codigo)
3. Depois de lancar tudo, commit.
Eu sei q fica foda de assimilar sem ver rodando.. entao, se vc quiser um exemplo pratico, me passa um email e eu te passo um blz?
10/06/2008
Eniorm
irei testar e posto os resultados
obrigado pela ajuda
11/06/2008
Eniorm
StartTransaction; DataSetMestre.Insert; DataSetDetalhe.Insert; Incluo a PK da tabela Mestre; Incluo a PK da tabela de Itens; Post; QueryExibeDetalhes.Close; Incluo o parâmetro PK da tabela Mestre; QueryExibeDetalhe.Open;
Todos esses componentes estão associados ao mesmo objeto Transaction, configurado para o nível de isolamento ReadCommited, mas tentei as 4 opções do componente e nenhuma funcionou.
Estranho: após o Post, inclui um ShowMessage para exibir o RecordCount do DataSetDetalhe, o mesmo indicava registros adicionados.
Porem, a query que deveria exibir os detalhes não exibe;
Bruno, se vc me puder passar o exemplo, meu email é: eniorm@gmail.com
ou para facilitar, caso vc queira, deixe disponível num ftp para que outros possam pegar,
vc pode usar esse que é de onde eu trabalho:
ftp.santafedosul.sp.gov.br/publico/
cordialmente,
11/06/2008
Eniorm
caso alguém queira dar uma olhada, deixei disponível para download no link abaixo
[url]ftp.santafedosul.sp.gov.br/publico/Teste_MasterDetail.rar[/url]
abraços
13/06/2008
Brunodsr
Estive doente nos ultimos dias(bronquite) e so to vendo o seu post hoje.
Vou fazer um exemplo do jeito que eu te falei e te dou um toque blz?
Um abraco,
13/06/2008
Eniorm
abraço
16/06/2008
Eniorm
após uma terrível luta com Transações, consegui implementar de acordo com minhas idéias iniciais (no primeiro post)
quem quiser a aplicação-exemplo está disponível em
[url]ftp.santafedosul.sp.gov.br/publico/Teste_MasterDetail_OK.rar[/url]
o exemplo possui o FDB, está compilado e junto com os sources.
Agradeço a todos que colaboraram para eu conseguir resolver essa bucha!
grande abraço a todos.
17/06/2008
Brunodsr
Eu to com o exemplo q te falei, so n consigo postar no ftp.
Se vc ainda quiser dar uma olhada da um toque blz?
17/06/2008
Eniorm
Amigos, eis aqui o exemplo criado pelo colega Bruno, deixei no ftp para fácil acesso a todos os interessados:
[url]ftp.santafedosul.sp.gov.br/publico/DataBase.rar[/url]
abraços
17/06/2008
Adriano_servitec
Depois na grid detail fiz 3 cadastros e fui gravar e esta gravando apenas o primeiro no banco o resto esta se perdendo, quando dou o commit.
Clique aqui para fazer login e interagir na Comunidade :)