SQL 服务器多级联路径通过添加独立主键解决
SQL Server Multiple Cascade Path Solved with adding independent primary key
我查看了这里关于堆栈溢出的几篇文章 SQL 服务器错误 1785:引入 FOREIGN KEY 约束可能会导致循环或多个级联路径。我发现不检查循环是 Microsoft 产品的一项功能,常见的建议是使用触发器来绕过它。
所以我的问题是:
如何在 SQL 服务器中的多个 table 上生成外键依赖项?
我错误地发现,如果我创建一个单独的独立 PRIMARY KEY,我可以创建具有多个级联路径的 table 而不会出错(并且它按预期工作)。作为参考,我是 运行 SQL Server 2019.
以下会产生错误:
CREATE TABLE t1 (
id bigint,
CONSTRAINT PK_t1 PRIMARY KEY CLUSTERED (id)
);
CREATE TABLE t2 (
id bigint,
CONSTRAINT PK_t2 PRIMARY KEY CLUSTERED (id)
);
CREATE TABLE cross_t1_t2 (
t1_id bigint,
t2_id bigint,
CONSTRAINT PK_cross_t1_t2 PRIMARY KEY CLUSTERED (t1_id,t2_id),
CONSTRAINT FK_cross_t1_t2_t1 FOREIGN KEY (t1_id)
REFERENCES customers (id)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT FK_cross_t1_t2_t2 FOREIGN KEY (t2_id)
REFERENCES addresses (id)
ON DELETE CASCADE
ON UPDATE CASCADE
);
由于我在任何地方都找不到这个答案,所以我将其张贴在这里作为触发器解决方法的替代方法。很高兴知道为什么会这样。
为了解决多重级联路径错误,您可以创建一个触发器来检查和删除上述记录 here。
或者你可以创建一个单独的列作为主键(可以自增IDENTITY
)
以下不会产生错误:
CREATE TABLE t3 (
id bigint,
CONSTRAINT PK_t3 PRIMARY KEY CLUSTERED (id)
)
CREATE TABLE t4 (
id bigint,
CONSTRAINT PK_t4 PRIMARY KEY CLUSTERED (id)
);
CREATE TABLE cross_t3_t4 (
id bigint,-- THE ONLY DIFFERENCE IS THE CREATION OF A SEPARATE PK
t3_id bigint,
t4_id bigint,
--Constraints
CONSTRAINT PK_cross_t3_t4 PRIMARY KEY CLUSTERED (id),
CONSTRAINT FK_cross_t3_t4_t3 FOREIGN KEY (t3_id)
REFERENCES t3 (id)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT FK_cross_t3_t4_t4 FOREIGN KEY (t4_id)
REFERENCES t4 (id)
ON DELETE CASCADE
ON UPDATE CASCADE
);
我查看了这里关于堆栈溢出的几篇文章 SQL 服务器错误 1785:引入 FOREIGN KEY 约束可能会导致循环或多个级联路径。我发现不检查循环是 Microsoft 产品的一项功能,常见的建议是使用触发器来绕过它。
所以我的问题是:
如何在 SQL 服务器中的多个 table 上生成外键依赖项?
我错误地发现,如果我创建一个单独的独立 PRIMARY KEY,我可以创建具有多个级联路径的 table 而不会出错(并且它按预期工作)。作为参考,我是 运行 SQL Server 2019.
以下会产生错误:
CREATE TABLE t1 (
id bigint,
CONSTRAINT PK_t1 PRIMARY KEY CLUSTERED (id)
);
CREATE TABLE t2 (
id bigint,
CONSTRAINT PK_t2 PRIMARY KEY CLUSTERED (id)
);
CREATE TABLE cross_t1_t2 (
t1_id bigint,
t2_id bigint,
CONSTRAINT PK_cross_t1_t2 PRIMARY KEY CLUSTERED (t1_id,t2_id),
CONSTRAINT FK_cross_t1_t2_t1 FOREIGN KEY (t1_id)
REFERENCES customers (id)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT FK_cross_t1_t2_t2 FOREIGN KEY (t2_id)
REFERENCES addresses (id)
ON DELETE CASCADE
ON UPDATE CASCADE
);
由于我在任何地方都找不到这个答案,所以我将其张贴在这里作为触发器解决方法的替代方法。很高兴知道为什么会这样。
为了解决多重级联路径错误,您可以创建一个触发器来检查和删除上述记录 here。
或者你可以创建一个单独的列作为主键(可以自增IDENTITY
)
以下不会产生错误:
CREATE TABLE t3 (
id bigint,
CONSTRAINT PK_t3 PRIMARY KEY CLUSTERED (id)
)
CREATE TABLE t4 (
id bigint,
CONSTRAINT PK_t4 PRIMARY KEY CLUSTERED (id)
);
CREATE TABLE cross_t3_t4 (
id bigint,-- THE ONLY DIFFERENCE IS THE CREATION OF A SEPARATE PK
t3_id bigint,
t4_id bigint,
--Constraints
CONSTRAINT PK_cross_t3_t4 PRIMARY KEY CLUSTERED (id),
CONSTRAINT FK_cross_t3_t4_t3 FOREIGN KEY (t3_id)
REFERENCES t3 (id)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT FK_cross_t3_t4_t4 FOREIGN KEY (t4_id)
REFERENCES t4 (id)
ON DELETE CASCADE
ON UPDATE CASCADE
);