Descobrir um erro de chave antes que o mesmo aconteça
19/10/2004
0
essa dúvida é meio maluca, mas tava precisando de um lance assim... as vezes temos uma tabela que possui 5 ou + FKs ... entao se excluirmos um registro dessa tabela, teremos um erro de chave se em algumas das outras tabelas tivermos um registro relativo... exemplo
tab1
id_tab1 PK
tab2
id_tab2 PK
id_tab1 FK
tab3
id_tab3 PK
id_tab1 FK
e assim vai ...
se eu tiver registros na tab2 ou tab3, na hora q excluir um registro de tab1 que existir em alguma das outras tabelas vai gerar o erro... a pergunta é: tem como esse erro ser previsto ( sem select.. pq ai é só usar ´NOT IN ( Select id_tab1 from tab2 )´?? nao sei se eu expliquei bem mas quem conseguir entender e puder ajudar eu agradeço
[]´s
Felipe_cduarte
Posts
19/10/2004
Fer_nanda
Bom, se eu entendi vamos lá.
Voce precisa verificar a integridade antes da exclusão de um registro.. para não craiar uma qry para essa verificação, fizemos uma função que cuida disso...o que faço é passar a sql para essa verificação.
//Verifica Integridade Referencial Function IntReferencial(StrSql: string; NomeBaseDados : TSQLConnection): extended; var qryIntReferencial: TSQLQuery; begin Try qryIntReferencial := TSQLQuery.Create(Application); qryIntReferencial.SQLConnection := NomeBaseDados; qryIntReferencial.Close; qryIntReferencial.Sql.Clear; qryIntReferencial.Sql.Text := StrSql; qryIntReferencial.Open; Result := qryIntReferencial.FieldByName(´Total´).Value; Except ShowMessage(´Erro encontrado na verificação de integridade referencial [0016]´); end; end;
Chamada
If IntReferencial(´Select Count(EmpCodigo) as Total from Funcionario where EmpCodigo = ´ + edtEmpCodigo.Text, frmMenuPrincipal.SQLConnection1) >= 1 then begin edit1.SetFocus; showmessage(´Exclusão negada, pois existem funcionários vinculados a esta empresa.´); Exit; end;
Espero que seja isso que esteja procurando :wink:
Até
20/10/2004
Felipe_cduarte
a idéia é +- essa, vou seguir o seu exemplo... neste seu módulo vc deve estar tentando excluir uma empresa certo ?? mas se este codigo da empresa fosse FK em outra tabela e se não existisse nenhum funcionario alocada a ela, o Result da função seria 0 e o sistema aceitaria excluir ... concorda ??? continuando com o seu exemplo, se o codigo da empresa fosse FK em mais 5 tabelas, teria q ser feito um bloco if..else if para validar todas as tabelas ... e se alguma tabela que tivesse esta FK fosse criada apos o desenvolvimento deste módulo, o mesmo teria q ser revisto e inserido a funcao... por isso queria encontrar uma formula até mesmo interna do SQL Server para fazer este tipo de validação .. acho q ainda tô enrolado pra explicar mas é isso :P
desde já agradeço pela ajuda
[]´s
PS: lembrei, olha só não estou criticando seu sistema, mas vc levantou uma boa questão pq trabalho com Delphi tb :P , aguardo seu reply
20/10/2004
Marcus.magalhaes
Vc pode ter uma idéia com este código :
[color=green:c2640370c4]Select so.name As ´FK name´, sob.name As ´Tbl Filha´, sobj.name As ´Tbl Mae´
From sysreferences sr Inner Join sysobjects so On sr.constid = so.id
Inner Join sysobjects sob On sr.fkeyid = sob.id
Inner Join sysobjects sobj On sr.rkeyid = sobj.id[/color:c2640370c4]
Nele vc tem o nome da FK, a tabela filha e a tabela Mãe, a partir daí, dá para vc ter idéia de como seguir para validar as diversas tabelas filhas, não importando se sua estrutura de dados mudar.
Espero ter ajudado.
Att,
20/10/2004
Felipe_cduarte
com essa qry dá pra descobrir as chaves, se juntarmos a ideia da Fernanda dá pra fazer, tipo
while ( not Qry.Eof ) do
IntReferencial()
e assim vai hehe..
mas o problema é q eu queria esse resultado em um select, tipo
case
when ( erro de alguma FK ) then ´Não´
else ´Sim´
end as Pode_excluir
+- isso ... mas pelo jeito nao deve dar pra fazer... vou ter q codificar mesmo.
Valeu de novo pela ajuda
[]´s
20/10/2004
Marcus.magalhaes
Só uma curiosidade, pq vc quer saber antes e não tratar o erro depois? Assim vc evitar toda uma série de leituras, q podem pesar na sua conexão.
Att,
21/10/2004
Felipe_cduarte
foi mal ai demorar pra responder ... o lance é o seguinte: na nossa aplicação, em um certo módulo, estaremos utilizando um componente checkbox, que tem 4 estados possiveis: marcado e habilitado, desmarcado e habilitado, marcado e desabilitado, desmarcado e desabilitado... queria conseguir com o CASE montar este SQL , que retornaria 1, 2, 3 e 4 por exemplo para cada estado do checkbox ( este SQL seria relativo a tabela mãe, como vc nomeou a mesma). Um desses estados, o marcado e desabilitado, seria o erro de chave, com isso o usuario nao poderia mexê-lo ( pq já se saberia que existem informações relativas ao registro ).. Estou começando agora a estudar as tabelas do sistema ( sysusers, syslogins, etc ...) mas me parece que está SQL não é possivel .. terei que tratá-lo na aplicação
pensei aki vou exemplificar:
situacao 1: existe tab mãe
situacao 2: nao existe tab mãe
situacao 3: erro FK
situacao 4: erro Unique Index
mas de qualquer forma valeu pela ajuda ... se tiver mais algum comentário , manda ver ! 8)
Clique aqui para fazer login e interagir na Comunidade :)