Conflitantes CASCADE e restringir requisitos chaves estrangeiras?

votos
2

Eu estou trabalhando em um banco de dados que rastreia arquivos e dependências em projetos. Resumidamente, tenho duas tabelas principais; A tabela lista Projetos Projeto nomes e outras propriedades, a tabela FILES lista arquivos. A cada entrada de arquivo aponta para um projeto como uma chave estrangeira definida para CASCATA, então se eu excluir um registro do projeto do banco de dados, todos os registros do arquivo desaparecer também. Por enquanto, tudo bem.

Agora eu tenho uma tabela de dependências adicionais. Cada registro na tabela de dependência é dois arquivos, especificando que o primeiro arquivo depende do segundo. Novamente, essas são chaves estrangeiras, o primeiro está definido para CASCATA (por isso, se eu excluir uma entrada de arquivo, este registro é excluído), mas o segundo é definida para restringir (então eu não estou autorizado a excluir uma entrada de arquivo se quaisquer outros arquivos dependem nele). Mais uma vez, tudo parece bom.

Infelizmente, parece que eu já não pode excluir um projeto com um único SQL delete! As tentativas de exclusão em cascata-apagar os arquivos, mas se algum deles aparecer na tabela de dependências, o RESTRINGIR chave estrangeira impede a exclusão (mesmo que esse registro na tabela de dependências serão removidos porque a outra coluna é cascata). A única solução que eu tenho é para calcular uma ordem exata para excluir os arquivos para que nenhum dos constrangimentos recorde dependência são violados, e remover os registros do arquivo um de cada vez antes de tentar remover o projeto.

Existe alguma maneira de configurar meu esquema banco de dados para um único SQL excluir da tabela de projetos irão propagar corretamente os outros exclusões? Estou usando Firebird 2.1, mas eu não sei se isso faz alguma diferença - parece que deve haver uma maneira de fazer este trabalho?

Publicado 09/12/2008 em 19:51
fonte usuário
Em outras línguas...                            


2 respostas

votos
4

Você não pode controlar a ordem de exclusão através de uma chave estrangeira em cascata, mas você pode ser capaz de projetar um gatilho PROJECTSpara excluir linhas em FILESque pertence a este projeto e também estão listados no DEPENDENCIEScomo dependente de outros FILES. Torná-lo um BEFORE DELETEgatilho, por isso deve ser executado antes que os efeitos em cascata.

Algo assim:

CREATE TRIGGER Del_Child_Files FOR PROJECTS
BEFORE INSERT IGNORE 
AS BEGIN
  FOR SELECT F.FILE_ID FROM FILES F JOIN DEPENDENCIES D 
      ON F.FILE_ID = D.CHILD_ID
    WHERE F.PROJECT_ID = OLD.PROJECT_ID
    INTO :file_id
  DO
    DELETE FROM FILES WHERE FILE_ID = :file_id;
  DONE
END

Então, quando você excluir um projeto, este apaga todos os arquivos "filho" de um projeto que são dependentes de outros arquivos, e este cascatas para excluir linhas em DEPENDENCIESpara que todos os arquivos restantes estão livres de dependências. Sua exclusão do projeto podem agora cascata para excluir esses arquivos.

Eu não testei isso e minha sintaxe Firebird pode ser enferrujado, mas talvez ele vai ajudar a começar.

Obviamente, por favor testar isso em uma cópia de seus dados, não os dados ao vivo!

Respondeu 09/12/2008 em 20:24
fonte usuário

votos
0

Será que o suporte ao sistema restrições, em que a restrição de verificação pode ser adiada até um ponto de cometer adiada?

Talvez isso é apenas uma coisa do Oracle embora.

Respondeu 09/12/2008 em 20:11
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more