2

我正在开发一个跟踪项目中文件和依赖项的数据库。简而言之,我有两个主表;PROJECTS 表列出项目名称和其他属性,FILES 表列出文件。每个文件条目都指向一个项目作为设置为 CASCADE 的外键,所以如果我从数据库中删除项目记录,所有文件记录也会消失。到现在为止还挺好。

现在我有一个额外的 DEPENDENCIES 表。依赖表中的每条记录都是两个文件,指定第一个文件依赖于第二个文件。同样,这些是外键,第一个设置为 CASCADE(因此,如果我删除一个文件条目,则该记录将被删除),但第二个设置为 RESTRICT(因此,如果有任何其他文件依赖,我不允许删除文件条目在上面)。再一次,一切似乎都很好。

不幸的是,我似乎不能再用一条 SQL 删除语句来删除项目了!删除尝试级联删除文件,但如果其中任何一个出现在 DEPENDENCIES 表中,则 RESTRICT 外键会阻止删除(即使依赖表中的该记录将被删除,因为另一列是 CASCADE)。我唯一的解决方法是计算删除文件的确切顺序,因此不会违反任何依赖记录约束,并在尝试删除项目之前一次删除文件记录。

有什么方法可以设置我的数据库模式,以便从项目表中删除单个 SQL 将正确地级联其他删除?我正在使用 Firebird 2.1,但我不知道这是否有什么不同 - 似乎应该有一种方法可以使这项工作?

4

2 回答 2

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 语法可能会生锈,但也许它会让你开始。

显然,请在您的数据副本上进行测试,而不是实时数据!

于 2008-12-09T19:24:31.383 回答
0

系统是否支持延迟约束,其中约束检查可以推迟到提交点?

也许这只是甲骨文的事情。

于 2008-12-09T19:11:08.587 回答