Dúvida com Mestre/Detalhe

Delphi

13/05/2004

Uso FB1.5 e Dbx com ClientDataSet.
Uso só componentes da Paleta Data Control e também criei um generator para q através de uma trigger, autoincrementar.
Minha dúvida é a seguinte: Como incluir a detalhe ao mesmo tempo que a mestre usando só componentes da Paleta Data Control??? O problema é que não consigo pegar a chave primária da mestre para relacionar com a estrangeira da detalhe.
Mas também não quero criar um campo na mestre que guarde o valor do generator.

+ ou - assim

procedure Tform1.BitBtn1Click(Sender: TObject);
begin
DataSource1.DataSet.Insert;
SQLDataSet2.Active:=False;
SQLDataSet2.CommandText:= ´Select * from DETALHE where coddetalhe = (Select max(codmestre) from MESTRE)´;
// Acho q o segredo está no sql, mas não consigo
// tentei também ao invés de (Select max(codmestre) from MESTRE)
// colocar (Select gen_id(generatormestre,0) from RDB$database)
SQLDataSet2.Active:=True;
DataSource2.DataSet.Insert;
end;

Alguém pode me ajudar?

Desde já meus agradecimentos.


G1b4

G1b4

Curtidas 0

Respostas

G1b4

G1b4

13/05/2004

Alguém por favor, me ajude!


GOSTEI 0
Eniorm

Eniorm

13/05/2004

Uso só componentes da Paleta Data Control e também criei um generator para q através de uma trigger, autoincrementar.
Minha dúvida é a seguinte: Como incluir a detalhe ao mesmo tempo que a mestre usando só componentes da Paleta Data Control??? O problema é que não consigo pegar a chave primária da mestre para relacionar com a estrangeira da detalhe.
Mas também não quero criar um campo na mestre que guarde o valor do generator.

Apenas uma sugestão, TENTE o seguinte:
A chave primaria é gerada qdo, no On Post ou no On New Record ??

Caso seja no On Post, então no evento AfterPost (após postar) do DataSet mestre que vc usa e use algo assim:
cod := DataSet.FieldByName(´CampoChave´).AsInteger;

E logo depois vc implementa a gravação do detalhe.

Ja fiz isso uma vez, usando IBDataSet e IBQuery/IBUpdateSQL


GOSTEI 0
G1b4

G1b4

13/05/2004

Caro Enio,
A trigger eh gerada depois do post.
A edição, consulta, exclusão funicionam normalmente.
O problema eh na inserção, pois pede-se o coddetalhe. Aew que está o problema...


GOSTEI 0
Eniorm

Eniorm

13/05/2004

Caro Enio, A trigger eh gerada depois do post. A edição, consulta, exclusão funicionam normalmente. O problema eh na inserção, pois pede-se o coddetalhe. Aew que está o problema...


Exato, no evento AfterPost vc usa:
coddetalhe := SeuDataSet.FieldByName(´CampoChave´).AsInteger;


Depois vc grava o detalhe usando o valor de coddetalhe
T+


GOSTEI 0
G1b4

G1b4

13/05/2004

Grato Enio,
Mas como lhe falei o problema não eh no post...
eh na inserção...
Vou ser mais claro..
Tenho uma pagecontrol no formulario e varias tabsheets.
Na primeira tab está os componentes relacionados da tabela mestre e no restante, da tabela detalhe.
O erro não ocorre qdo clico no botão:

procedure Tform1.BitBtn1Click(Sender: TObject);
begin
DataSource1.DataSet.Insert;
SQLDataSet2.Active:=False;
SQLDataSet2.CommandText:= ´Select * from DETALHE where coddetalhe = (Select max(codmestre) from MESTRE)´;
// Acho q o segredo está no sql, mas não consigo
// tentei também ao invés de (Select max(codmestre) from MESTRE)
// colocar (Select gen_id(generatormestre,0) from RDB$database)
SQLDataSet2.Active:=True;
DataSource2.DataSet.Insert;
end;

Mas qdo o foco vai para algum componente relacionado a detalhe:

field codmestre: must have a value.

Se alguem puder me ajudar, eu agradeço...


GOSTEI 0
G1b4

G1b4

13/05/2004

Galera, depois de muito teste, posso afirmar que o problema se dá no Insert da tabela detalhe. Quando um registro é inserido na tabela detalhe, pede-se o valor da chave estrangeira da detalhe para começar a relacionar com a mestre. O problema é que o valor que ele pede, ainda não foi gerado e não posso simplesmente gerar um valor aleatório sem o registro mestre existir. Será q o único jeito é gravar o registro mestre e depois postá-lo, gerando assim a chave primária e logo em seguida dar insert no detalhe, tendo assim a chave estrangeira, editando o mestre e em seguida inserindo o detalhe???

Aguardo respostas...


GOSTEI 0
G1b4

G1b4

13/05/2004

Alguém me ajude !!!


GOSTEI 0
G1b4

G1b4

13/05/2004

Tentei assim:
procedure Tdm.ClientDataSet1AfterInsert(DataSet: TDataSet);
begin
DataSet.Post; //relacionado a tabela mestre
DataSet.Edit;
SQLDataSet2.Active:=False;
SQLDataSet2.SQL.Text:=´Select * from DETALHE where coddetalhe=´+
IntToStr(DataSet.FieldByName(´codmestre´).AsInteger);
DataSource2.DataSet.Refresh;
DataSource2.DataSet.Insert;
end;

Mas mesmo assim, não há relacionamento...
Alguém me ajude.


GOSTEI 0
G1b4

G1b4

13/05/2004

Consegui dar um passo no problema.

var
codigo : integer
begin
ClientDataSetMestre.Append ;
ClientDataSetMestre.Post;
//logo após o post a chave eh gerada
ClientDataSetMestre.Active:=False;
ClientDataSetDetalhe.Active:=False;
ClientDataSetMestre.CommandText:=´select * from MESTRE where codmestre=´+IntToStr(codigo);
ClientDataSetMestre.Active:=True;
ClientDataSetDetalhe.Active:=True;
ClientDataSetMestre.Edit;
ClientDataSetDetalhe.Insert;
end;

O erro q aparece é que o campo codmestre tem q ter um valor.


GOSTEI 0
G1b4

G1b4

13/05/2004

Esqueci da atribuição da variável, esse só é um exemplo. No meu programa ela jah estava...
var
codigo : integer
begin
ClientDataSetMestre.Append ;
ClientDataSetMestre.Post;
codigo:=ClientDataSetMestre.FieldByName(´codmestre´).AsInteger;
//logo após o post a chave eh gerada
ClientDataSetMestre.Active:=False;
ClientDataSetDetalhe.Active:=False;
ClientDataSetMestre.CommandText:=´select * from MESTRE where codmestre=´+IntToStr(codigo);
ClientDataSetMestre.Active:=True;
ClientDataSetDetalhe.Active:=True;
ClientDataSetMestre.Edit;
ClientDataSetDetalhe.Insert;
end;


GOSTEI 0
POSTAR