Violação de Foreign Key
Estou tendo um problema para incluir registros. O cenário é o seguinte:
- Uso Delphi 7 com Firebird 1.5
- Num BD tenho uma tabela mestre ´Contrato´ e duas detalhes ´Servicos´ e ´Parcelas´, as duas tabelas detalhes estão relacionadas com a tabela mestre através de um campo do tipo Foreign Key, o qual serve para garantir a integridade dos dados.
- Uso o conjunto DataSetProvider, ClientDataSet, DataSource para cada tabela. Cada um dos DataSetProvider é ligado a um TMDOQuery (componente de conectividade similar o TIBQuery, que faz parte da biblioteca MDO ou Mercury Database Objects)
-Para conexão com o Bd usa o MDODatabase que é similar ao IBDatabase.
Os procedimentos para gravação de dados é o seguinte, lembrando que o processo é feito em cima do ClientDataSet:
O erro ocorre somente na inclusão, com a mensagem de violação de chave estrangeira. Isso é realmente justificável pois não posso incluir dados em tabelas detalhes sem antes incluir os dados da tabela mestre.
Mas como posso resolver essa situação sem retirar os chaves estrangeiras das tabelas detalhes?
P.S. Tentei usar o um campo do tipo TDatasetField para as tabelas detalhes mas o componente ClientDataSet da tabelas mestre não aceita mais que um campo, se colocar mais que um dá uma mensagem ´Mismatch in datapacket´
Grato pela atenção
Luiz
- Uso Delphi 7 com Firebird 1.5
- Num BD tenho uma tabela mestre ´Contrato´ e duas detalhes ´Servicos´ e ´Parcelas´, as duas tabelas detalhes estão relacionadas com a tabela mestre através de um campo do tipo Foreign Key, o qual serve para garantir a integridade dos dados.
- Uso o conjunto DataSetProvider, ClientDataSet, DataSource para cada tabela. Cada um dos DataSetProvider é ligado a um TMDOQuery (componente de conectividade similar o TIBQuery, que faz parte da biblioteca MDO ou Mercury Database Objects)
-Para conexão com o Bd usa o MDODatabase que é similar ao IBDatabase.
Os procedimentos para gravação de dados é o seguinte, lembrando que o processo é feito em cima do ClientDataSet:
var erro: integer; ... MdoDatabase.StarTransaction; erro := cdsContrato.ApplyUpdates(0); if erro = 0 then erro := cdsServico.ApplyUpdates(0); if erro = 0 then erro := cdsParcelas.ApplyUpdates(0); if erro = 0 then MdoDatabase.Commit else MdoDatabase.Rollback;
O erro ocorre somente na inclusão, com a mensagem de violação de chave estrangeira. Isso é realmente justificável pois não posso incluir dados em tabelas detalhes sem antes incluir os dados da tabela mestre.
Mas como posso resolver essa situação sem retirar os chaves estrangeiras das tabelas detalhes?
P.S. Tentei usar o um campo do tipo TDatasetField para as tabelas detalhes mas o componente ClientDataSet da tabelas mestre não aceita mais que um campo, se colocar mais que um dá uma mensagem ´Mismatch in datapacket´
Grato pela atenção
Luiz
Lab
Curtidas 0
Respostas
Rodolpho123
24/01/2006
1-Na tabela mestre, altere a trigger que gera o valor do campo chave (creio eu que vc esteja utilizando assim) apar somente pegar o valor do [b:e2fc5076f7]generator[/b:e2fc5076f7] se vc passar um valor nulo, ex:
2-Na inserção do registro pelo ClientDataSet, atribuia o valor do campo chave através de um select em um outro Cds qualquer para pegar o valordo [b:e2fc5076f7]generator[/b:e2fc5076f7] referente. O sql ficaria assim:
3- Atribua o valor ao campo chave, ex:
4-Pronto! Agora vc tem o valor do campo chave para aplicar nas FK´s das tabelas filhas...[/code]
if new.idcampo is null then new.idcampo = gen_id(meugerador,1);
2-Na inserção do registro pelo ClientDataSet, atribuia o valor do campo chave através de um select em um outro Cds qualquer para pegar o valordo [b:e2fc5076f7]generator[/b:e2fc5076f7] referente. O sql ficaria assim:
select gen_id(meugerador,1) as valorchave from rdb$database
3- Atribua o valor ao campo chave, ex:
CdsMestre.FieldByName(´CAMPOCHAVE´).AsInteger := CdsGerador.FieldByName(´VALORCHAVE´).AsInteger;
4-Pronto! Agora vc tem o valor do campo chave para aplicar nas FK´s das tabelas filhas...[/code]
GOSTEI 0