【问题标题】:Can't find where multiple cascade paths or cycles are in SQL Code?在 SQL 代码中找不到多个级联路径或循环的位置?
【发布时间】:2015-09-04 15:30:54
【问题描述】:

我不断收到以下错误

消息 1785,第 16 级,状态 0,第 99 行 在表 >'linkUserGroup' 上引入 FOREIGN KEY 约束 'FK_linkUserGroup_tblStudent' 可能会导致循环或多个级联路径。指定 ON DELETE ?>NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。 消息 1750,第 16 级,状态 0,第 99 行 无法创建约束或索引。查看以前的错误。

我无法理解一个循环或多个级联路径是如何可能的?我也无法理解对 TeacherID 的 FK 约束如何不会导致同样的问题?我的理解是,如果父 StudentID 被删除,那么通过在子表中指定 On Delete No Action 应确保不会从子表中删除记录。我不明白他们的其他路径或可能的循环如何?请帮忙

CREATE TABLE tblUserAccount (
uaUserAccountID INT  IDENTITY (1,1) CONSTRAINT PK_tblUserAccount PRIMARY KEY CLUSTERED,
uaUserAccountTitle NVARCHAR (50) NOT NULL,
uaUserAccountFirstName NVARCHAR (50) NOT NULL,
uaUserAccountSurname  NVARCHAR (50) NOT NULL,
uaUserAccountUserName NVARCHAR (50) NOT NULL,
uaUserAccountPassword  NVARCHAR (50) NOT NULL,
uaDateTimeModified DATETIME 
    CONSTRAINT DF_tblUserAccount_DateTimeModified DEFAULT SYSDATETIME()
);

CREATE TABLE tblRole (
rRoleID INT  IDENTITY (1, 1) CONSTRAINT PK_tblRole PRIMARY KEY CLUSTERED,
rRole NVARCHAR (50),
rRoleDescription NVARCHAR (MAX) NULL,
rDateTimeModified DATETIME 
    CONSTRAINT DF_tblRole_DateTimeModified DEFAULT SYSDATETIME()
);

CREATE TABLE linkUserAccountRole (
uarUserAccountID INT,
uarRoleID   INT,
uarDateTimeModified DATETIME 
     CONSTRAINT DF_linkUserAccountRole_DateTimeModified DEFAULT SYSDATETIME()
    ,CONSTRAINT PK_linkUserAcccountRole 
        PRIMARY KEY CLUSTERED (uarUserAccountID , uarRoleID)
    ,CONSTRAINT FK_linkUserAcccountRole_tblRole 
        FOREIGN KEY (uarRoleID) 
        REFERENCES tblRole (rRoleID) 
        ON DELETE NO ACTION
        ON UPDATE CASCADE
    ,CONSTRAINT FK_linkUserAcccountRole_tblUserAccount 
        FOREIGN KEY (uarUserAccountID) 
        REFERENCES tblUserAccount (uaUserAccountID) 
        ON DELETE NO ACTION 
        ON UPDATE CASCADE
);

CREATE TABLE tblTeacher (
tTeacherID  INT CONSTRAINT PK_tblTeacher PRIMARY KEY CLUSTERED, 
tUserAccountID INT,
tDateTimeModified DATETIME 
    CONSTRAINT DF_tblTeacher_DateTimeModified DEFAULT SYSDATETIME(),
    CONSTRAINT FK_tblTeacher_tblUserAccount 
        FOREIGN KEY (tUserAccountID) 
        REFERENCES tblUserAccount(uaUserAccountID)  
        ON DELETE CASCADE 
        ON UPDATE CASCADE
);

CREATE TABLE tblStudent (
sStudentID  INT CONSTRAINT PK_tblStudent PRIMARY KEY CLUSTERED, 
sUserAccountID INT,
sDateTimeModified DATETIME 
    CONSTRAINT DF_tblStudent_DateTimeModified DEFAULT SYSDATETIME(),
    CONSTRAINT FK_tblStudent_tblUserAccount 
        FOREIGN KEY (sUserAccountID) 
        REFERENCES tblUserAccount(uaUserAccountID)  
        ON DELETE CASCADE 
        ON UPDATE CASCADE

);

CREATE TABLE tblKeyStage (
ksKeyStageGroupID INT IDENTITY (1,1) CONSTRAINT PK_tblKeyStage PRIMARY KEY CLUSTERED,
ksKeyStageTitle NVARCHAR (50) NOT NULL,
ksKeyStageDescription  NVARCHAR(50),
ksDateTimeModified DATETIME 
     CONSTRAINT DF_tblKeyStage_DateTimeModified DEFAULT SYSDATETIME() 
    ,CONSTRAINT UQ_tblKeyStage_KeyStageTitle UNIQUE (ksKeyStageTitle)
);

CREATE TABLE tblYearGroup (
ygYearGroupID INT IDENTITY (1,1) CONSTRAINT PK_tblYearGroup PRIMARY KEY CLUSTERED,
ygYearGroupTitle NVARCHAR (50) NOT NULL,
ygYearGroupDescription NVARCHAR(50),
ygDateTimeModified DATETIME 
     CONSTRAINT DF_tblYearGroup_DateTimeModified DEFAULT SYSDATETIME()
    ,CONSTRAINT UQ_tblYearGroup_YearGroupTitle UNIQUE (ygYearGroupTitle)
);

CREATE TABLE tblClassGroup (
cgClassGroupID INT IDENTITY (1,1) CONSTRAINT PK_tblClassGroup PRIMARY KEY CLUSTERED,
cgClassGroupTitle NVARCHAR (50) NOT NULL,
cgClassGroupDescription    NVARCHAR (50),
cgDateTimeModified  DATETIME 
     CONSTRAINT DF_tblClassGroup_DateTimeModified DEFAULT SYSDATETIME()
    ,CONSTRAINT UQ_tblClassGroup_ClassGroupTitle UNIQUE (cgClassGroupTitle)
);

CREATE TABLE tblLearningGroup (
lgLearningGroupID INT IDENTITY (1,1) CONSTRAINT PK_tblLearningGroup PRIMARY KEY CLUSTERED,
lgLearningGroupTitle NVARCHAR (50) NOT NULL,
lgLearningGroupDescription NVARCHAR (50),
lgDateTimeModified DATETIME 
     CONSTRAINT DF_tblLearningGroup_DateTimeModified DEFAULT SYSDATETIME()
    ,CONSTRAINT UQ_tblLearningGroup_LearningGroupTitle UNIQUE (lgLearningGroupTitle)
);

CREATE TABLE tblLearningGroup (
lgLearningGroupID INT IDENTITY (1,1) CONSTRAINT PK_tblLearningGroup PRIMARY KEY CLUSTERED,
lgLearningGroupTitle NVARCHAR (50) NOT NULL,
lgLearningGroupDescription NVARCHAR (50),
lgDateTimeModified DATETIME 
     CONSTRAINT DF_tblLearningGroup_DateTimeModified DEFAULT SYSDATETIME()
    ,CONSTRAINT UQ_tblLearningGroup_LearningGroupTitle UNIQUE (lgLearningGroupTitle)
);

CREATE TABLE linkUserGroup (
ugTeacherID INT,
ugStudentID INT,
ugKeyStageGroupID INT,
ugYearGroupID INT,
ugClassGroupID INT,
ugLearningGroupID INT,
ugDateTimeModified DATETIME 
     CONSTRAINT DF_linkUserGroup_DateTimeModified DEFAULT SYSDATETIME()
    ,CONSTRAINT PK_linkUserGroup 
        PRIMARY KEY CLUSTERED (ugTeacherID, ugStudentID, ugClassGroupID, ugLearningGroupID)
    ,CONSTRAINT FK_linkUserGroup_tblTeacher 
        FOREIGN KEY (ugTeacherID) 
        REFERENCES tblTeacher (tTeacherID)
        ON DELETE NO ACTION 
        ON UPDATE CASCADE
    ,CONSTRAINT FK_linkUserGroup_tblStudent 
        FOREIGN KEY (ugStudentID) 
        REFERENCES tblStudent (sStudentID)
        ON DELETE NO ACTION 
        ON UPDATE CASCADE
    ,CONSTRAINT FK_linkUserGroup_tblKeyStage 
        FOREIGN KEY (ugKeyStageGroupID) 
        REFERENCES tblKeyStage (ksKeyStageGroupID)
        ON DELETE NO ACTION
        ON UPDATE CASCADE
    ,CONSTRAINT FK_linkUserGroup_tblYearGroup 
        FOREIGN KEY (ugYearGroupID) 
        REFERENCES tblYearGroup (ygYearGroupID)
        ON DELETE NO ACTION
        ON UPDATE CASCADE
    ,CONSTRAINT FK_linkUserGroup_tblClassGroup
        FOREIGN KEY (ugClassGroupID) 
        REFERENCES tblClassGroup (cgClassGroupID)
        ON DELETE NO ACTION 
        ON UPDATE CASCADE
    ,CONSTRAINT FK_linkUserGroup_tblLearningGroup 
        FOREIGN KEY (ugLearningGroupID) 
        REFERENCES tblLearningGroup (lgLearningGroupID)
        ON DELETE NO ACTION
        ON UPDATE CASCADE
    ,CONSTRAINT UQ_linkUserGroup_PK_YearGroupID 
        UNIQUE (ugTeacherID, ugStudentID, ugClassGroupID, ugLearningGroupID, ugYearGroupID) 
);      

【问题讨论】:

    标签: sql-server


    【解决方案1】:

    tblUserAccountlinkUserGroup之间存在多个级联路径:

    tblUserAccount -> tblTeacher -> linkUserGroup
    tblUserAccount -> tblStudent -> linkUserGroup
    

    不允许的不是FK约束本身,而是动作:ON UPDATE CASCADE

    您可以为FK_linkUserGroup_tblTeacher 指定ON UPDATE CASCADE,或为FK_linkUserGroup_tblStudent 指定ON UPDATE CASCADE,但不能同时指定两者。

    您的ON DELETE 已经标记为NO ACTION,所以没问题。 ON UPDATE 你应该决定做什么。

    有两种选择:

    1) 禁止更新参与 FK 约束的密钥。

    为此,请指定ON UPDATE NO ACTION,或者完全删除ON UPDATE 子句,因为这是外键约束的默认行为。

    考虑到更新主键通常不是一个好主意(无论它是否被外键引用),我会推荐这个选项。

    2) 如果更改的sStudentIDtTeacherIDlinkUserGroup 的自动传播确实是您想要的,那么您可以使用触发器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-17
      • 2018-08-10
      • 2015-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多