Fórum Inserção com MasterSource e MasterFields #313520
20/02/2006
0
Uso os componentes datasource, dataset provider, client datasets, SQLDatasets e SQLConnection. Suponham que eles estejam conectados corretamente.
Tenho um clientdataset ´A´ que representa uma tabela ´revista´, e outro ´B´, que representa uma tabela ´reportagem´.
A propriedade MasterSource do ´B´ aponta para o ´A´ e o masterfield contém o relacionamento entre as duas tabelas.
Quando eu insiro um novo registro, no mesmo form eu insiro os dados da revista e já adiciono todas as reportagens que ela contém. Ou seja, nessa situação a revista está sendo inserida juntamente com as reportagens dela.
O problema é que quando eu salvo, aparece um erro dizendo que o campo ´cod_revista´, do ´B´, deve ter um valor ( ´cod_revista must have a value´ ), porém, ele já está no relacionamento do masterfields !
Quando eu estou em modo de edição, funciona perfeito, pois a chave primária de ´revista´ já existe.
Uso Firebird 1.5 com generator + trigger para criação de chaves primárias.
Resumindo: como eu posso inserir um novo registro, utilizando a estrutura de form que eu citei (cadastro da revista e das reportagens ao mesmo tempo), utilizando MasterSource/MasterFields ? Devo utilizar outro método para isso?
Obrigado, pessoal !
Marcelocda
Curtir tópico
+ 0Posts
20/02/2006
Rafael Gomes
para que voce possa inserir os registros detalhes com sucesso, a chave primaria da sua tabela mestre DEVE ter um valor. se nao tiver como o delphi vai relacionar as duas tabelas????
no modo de edição, creio que voce ja inseriu o registro no banco de dados e o valor da chave primaria ja existe, logo nao terá problemas para inserir os registros detalhes ...
creio que vc esta querendo inserir os registros detalhe sem antes dar um post na sua tabela mestre.
se nao for isso volte a postar!!
[]s
Gostei + 0
21/02/2006
Marcelocda
a estrutura aqui está da seguinte forma:
1) Dou um Post no cds mestre (somente uma vez, testando se o estado dele está em dsInsert ou dsEdit) ao adicionar uma reportagem
2) Dou um Post no cds detalhe para cada reportagem adicionada
3) Na hora de salvar, eu faço um applyupdates(-1) no cds mestre e em seguida outro no cds detalhe
Continua dando o mesmo erro :(
Será que isso tem a ver com o fato de eu utilizar um generator junto com um trigger para a geração de chaves primárias ?
Gostei + 0
21/02/2006
Marcelocda
Gostei + 0
22/02/2006
Marcelocda
dModule.IniciaTransacao(); dModule.cdsReportagem.Post; dModule.cdsExemplar.Post; dModule.cdsExemplar.ApplyUpdates(-1); dModule.cdsExemplar.Refresh; dModule.cdsReportagem.Edit; dModule.cdsReportagemCOD_EXEMPLAR.AsInteger := dModule.cdsExemplarCOD.AsInteger; dModule.cdsReportagem.ApplyUpdates(-1); dModule.Commit();
Bem, pessoal, o que está acontecendo é o seguinte:
1. Continua dando o mesmo erro, mesmo eu salvando o mestre primeiro.
2. Após o Refresh do cds mestre, como pude comprovar no debug, ele realmente está atribuindo o código gerado ao campo COD_EXEMPLAR, do cds detalhe. Porém, ao salvar o cds detalhe, ele continua acusando que COD_EXEMPLAR é null.
E uma coisa muito estranha que acontece:
a) No meu generator o valor corrente é 29, porém, o valor que está sendo atribuído ao COD do cds mestre é 6. Por quê isso acontece?
Após encontrar o mesmo erro, eu tentei atribuir o código ´na mão´, como foi visto na penúltima linha, antes do applyupdates do cds detalhe, e mesmo assim, continua acusando o erro de NULL no COD_EXEMPLAR.
O update mode está como UpWhereKeyOnly.
Por favor, pessoal, alguém poderia me dizer o que está errado?
Gostei + 0
22/02/2006
Paullsoftware
vc está apontando os campos corretos no código do gerador??
tipo, o código da minha Trigger é esse:
CREATE TRIGGER CLIENTES_BI FOR CLIENTES ACTIVE BEFORE INSERT POSITION 0 AS BEGIN IF (NEW.CODIGO IS NULL) THEN NEW.CODIGO = GEN_ID(GEN_CLIENTES_ID,1); END
só um detalhe, como está o valor [b:00fa1136fa]Default[/b:00fa1136fa] do seu campo código, tente incluir dados pelo próprio banco e veja se o [b:00fa1136fa]GERADOR [/b:00fa1136fa] esta funcionando, uma vez aconteceu comigo de não funcionar, mais por que o [b:00fa1136fa]Default[/b:00fa1136fa] do campo código estava 0...
Post aqui o resultado!
Gostei + 0
22/02/2006
Emerson Nascimento
dModule.IniciaTransacao(); dModule.cdsReportagem.Post; dModule.cdsExemplar.Post; dModule.cdsExemplar.ApplyUpdates(-1); dModule.cdsExemplar.Refresh; dModule.cdsReportagem.First; // primeiro registro while not dModule.cdsReportagem.Eof do begin dModule.cdsReportagem.Edit; dModule.cdsReportagemCOD_EXEMPLAR.AsInteger := dModule.cdsExemplarCOD.AsInteger; dModule.cdsReportagem.Post; // grava o valor do "mestre" dModule.cdsReportagem.Next; // passa para o próximo registro end; dModule.cdsReportagem.ApplyUpdates(-1); // aplica as alterações dModule.Commit();
veja se assim dá certo. o problema está no fato de a ligação master/detail não ter (infelizmente) o recurso de [i:7d955c1fd1]propagate changes[/i:7d955c1fd1] do nesteddataset. de qualquer forma faça o teste e nos avise sobre o resultado.
Gostei + 0
22/02/2006
Marcelocda
De qualquer forma, a lógica do Émerson está correta. Só que no meu caso eu teria que fazer umas coisas chatas no clientdataset, como achar o registro que acabou de ser inserido e filtrar o cds detalhe, já que nos meus cds estão todos os registros, pois também os utilizo para visualização em grid. Não sei se isso é trivial, porém, não quis perder mais tempo com isso.
Agora cá entre nós, essa implementação de mestre-detalhe no Delphi é bizarra, hein? Não propagar o valor da chave primária que foi inserida...Acaba servindo apenas para listagem e filtro mesmo.
PaullSoftware, o generator e o trigger estão corretos :)
Obrigado pelas respostas de todos !
São esses detalhes que eu busco nos livros e não acho...Coisas como a não propagação dos valores do cds mestre, contidos em um relacionamento mestre-detalhe;
No geral, os livros de delphi que vejo são muito superficiais...
Se alguém puder me indicar um livro BOM mesmo, que tenha um nível de detalhes desse tipo...Ficaria muito agradecido !
Valeu, pessoal !
Obrigado a todos e em especial ao Émerson !
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)