Pergunta

Eu estou trabalhando em um banco de dados que os arquivos de faixas e dependências em projetos. Resumidamente, tenho duas tabelas principais; A tabela lista Projetos Projeto nomes e outras propriedades, os arquivos de arquivos tabela lista. A cada entrada de arquivo aponta para um projeto como um conjunto de chave estrangeira em cascata, por isso, se eu excluir um registro do projeto do banco de dados, todos os registros do arquivo desaparecer também. Tão longe, tão bom.

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 já não posso excluir um projeto com uma instrução de exclusão único SQL! As tentativas de exclusão para cascata apagar os arquivos, mas se algum deles aparecer na tabela de dependências, o RESTRINGIR impede de chave estrangeira 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

Foi útil?

Solução

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 em PROJECTS a linhas de exclusão em FILES que pertence a este projeto e também estão listados no DEPENDENCIES como dependente de outros FILES . Torná-lo um gatilho BEFORE DELETE, por isso deve ser executado antes que os efeitos em cascata.

Algo parecido com isto:

CREATE TRIGGER Del_Child_Files FOR PROJECTS
BEFORE INSERT
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

Assim, 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 linhas de exclusão em DEPENDENCIES para 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 você começar.

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

Outras dicas

O sistema suporta diferido restrições, em que a restrição de verificação pode ser adiada até um ponto de cometer?

Talvez seja só uma coisa a Oracle embora.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top