我正在开发一个跟踪项目中的文件和依赖项的数据库。简而言之,我有两个主要表格; PROJECTS表列出了项目名称和其他属性,FILES表列出了文件。每个文件条目都指向项目作为设置为CASCADE的外键,因此如果从数据库中删除项目记录,则所有文件记录也会消失。到目前为止,非常好。
现在我有一个额外的DEPENDENCIES表。依赖关系表中的每个记录都是两个文件,指定第一个文件取决于第二个文件。同样这些是外键,第一个设置为CASCADE(所以如果删除文件条目,则删除此记录),但第二个设置为RESTRICT(因此,如果任何其他文件依赖,则不允许删除文件条目在上面)。再一次,一切似乎都很好。
不幸的是,我似乎无法再使用单个SQL删除语句删除项目!删除尝试级联删除文件,但如果其中任何一个出现在DEPENDENCIES表中,RESTRICT外键将阻止删除(即使依赖表中的该记录将被删除,因为另一列是CASCADE)。我唯一的解决方法是计算删除文件的确切顺序,以便不违反任何依赖性记录约束,并在尝试删除项目之前一次删除一个文件记录。
有没有办法设置我的数据库模式,以便从项目表中删除一个SQL将正确级联其他删除?我正在使用Firebird 2.1,但我不知道这是否有任何区别 - 似乎应该有办法使这项工作?
答案 0 :(得分:4)
您无法通过级联外键控制删除顺序,但您可以在PROJECTS
上设计触发器以删除FILES
中属于此项目的行,并且也是在DEPENDENCIES
中列出,依赖于其他FILES
。使它成为BEFORE DELETE
触发器,因此它应该在级联效果之前执行。
这样的事情:
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
因此,当您删除项目时,这会删除依赖于其他文件的项目的所有“子”文件,并且此级联删除DEPENDENCIES
中的行,以便所有剩余文件都没有依赖项。您删除项目现在可以级联删除这些文件。
我没有对此进行测试,我的Firebird语法可能会生锈,但也许它会让你开始。
显然,请在您的数据副本上测试,而不是实时数据!
答案 1 :(得分:0)
系统是否支持延迟约束,其中约束检查可以推迟到提交点?
可能这只是甲骨文的事情。