Sql 冲突级联和限制外键要求?

Sql 冲突级联和限制外键要求?,sql,database,database-design,firebird,Sql,Database,Database Design,Firebird,我正在开发一个数据库,用于跟踪项目中的文件和依赖项。简而言之,我有两个主要的表格;“项目”表列出项目名称和其他特性,“文件”表列出文件。每个文件条目都指向一个项目,作为设置为级联的外键,因此如果我从数据库中删除一个项目记录,所有文件记录也会消失。到目前为止,一切顺利 现在我有了一个附加的依赖项表。依赖关系表中的每条记录是两个文件,指定第一个文件依赖于第二个文件。同样,这些是外键,第一个设置为级联(因此,如果我删除一个文件条目,该记录将被删除),但第二个设置为限制(因此,如果任何其他文件依赖于它,

我正在开发一个数据库,用于跟踪项目中的文件和依赖项。简而言之,我有两个主要的表格;“项目”表列出项目名称和其他特性,“文件”表列出文件。每个文件条目都指向一个项目,作为设置为级联的外键,因此如果我从数据库中删除一个项目记录,所有文件记录也会消失。到目前为止,一切顺利

现在我有了一个附加的依赖项表。依赖关系表中的每条记录是两个文件,指定第一个文件依赖于第二个文件。同样,这些是外键,第一个设置为级联(因此,如果我删除一个文件条目,该记录将被删除),但第二个设置为限制(因此,如果任何其他文件依赖于它,则不允许我删除文件条目)。同样,一切似乎都很好

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


是否有任何方法可以设置我的数据库模式,以便从projects表中删除一个SQL将正确地级联其他删除?我使用的是Firebird 2.1,但我不知道这是否有什么区别-似乎应该有一种方法来实现这一点?

系统是否支持延迟约束,即可以将约束检查延迟到提交点


不过,这可能只是Oracle的事情。

您无法通过级联外键控制删除顺序,但您可以在
项目
上设计一个触发器,删除属于此项目的
文件
中的行,这些行也列在
依赖项
中,依赖于其他
文件
。在删除之前将其设置为
触发器,以便在级联效果之前执行

大概是这样的:

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
因此,当您删除一个项目时,这将删除项目中依赖于其他文件的所有“子”文件,并级联删除
依赖项中的行
,因此所有剩余文件都没有依赖项。您对项目的删除现在可以级联删除这些文件

我还没有测试过这个,我的Firebird语法可能已经生锈了,但也许它可以让你开始


显然,请在您的数据副本上测试这一点,而不是实时数据

Firebird不支持延迟约束。我非常喜欢在触发器中而不是在应用程序代码中这样做。我会试一试,看起来这将是我的答案:)