我有一个表t1,它有一个主键t1id。我有另一个表t2,它有一个t1id列,它是t1表的t1id的forign键。请看查询
create table T1
(
t1idint primary key IDENTITY(1,1),
Name varchar(200) not null
);
create table T2
(
t2idint primary key IDENTITY(1,1),
t1id int,
nod bigint,
foreign key ( t1id) references T1(t1id)
);
以及更多与T2表相关联的表格,我没有在这里显示。
我在表T1和T2中都插入了一些值。
现在要从T1中删除一行,我必须先从T2删除一行,然后由于foriegn密钥关系,我才能从T1中删除一行。
所以我认为添加级联约束是个好主意
我试过以下
ALTER TABLE T2
ADD CONSTRAINT fk_T2id
FOREIGN KEY (t1id)
REFERENCES T1(t1id)
ON DELETE CASCADE;
但是我收到了以下错误
Msg 1785,Level 16,State 0,Line 1 在表'T2'上引入FOREIGN KEY约束'fk_t1id'可能会导致循环或多个级联路径。指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。 Msg 1750,Level 16,State 0,Line 1 无法创建约束。查看以前的错误。
答案 0 :(得分:1)
我发现自己多次陷入困境,但从未使用过级联。我做了一个SP,它将获取我想要删除的ID,并且我在事务中自己执行删除操作。见例子
CREATE PROCEDURE [dbo].[spConfiguration_Table1_Del]
@ID int
AS
Declare @ERR int
set @ERR = 0
begin tran
DELETE FROM Table1 WHERE ID = @ID
set @ERR = @@Error
if @ERR = 0 begin
DELETE FROM Table2 WHERE ID IN (SELECT ID FROM Table3 WHERE ID = @ID)
set @ERR = @@Error
end
if @ERR = 0 begin
DELETE FROM Table3 WHERE ID = @ID
set @ERR = @@Error
end
if @ERR = 0 commit tran
else rollback tran
通过这种方式,您可以控制删除的发生方式,如果从一个表中删除时出错,则事务将回滚所有已删除的行,并保持数据的一致性。