Ily*_*kov 4 t-sql sql-server cascading-deletes
我有一个巨大的遗留数据库,其中一个表有多个外键指向另一个表,并且看不到一个级联,类似于下面的示例表:
create table Users (
Id int primary key identity,
Name varchar(max)
)
create table Products (
Id int primary key identity,
Name varchar(max),
CreatedBy int foreign key references Users(Id),
UpdatedBy int foreign key references Users(Id)
)
insert into Users values('Bar')
insert into Users values('Baz')
insert into Products values('Foo', 1, 2)
Run Code Online (Sandbox Code Playgroud)
我需要能够删除一些旧数据,但它当然会引发引用异常:
delete from Users where Name='Bar'
Run Code Online (Sandbox Code Playgroud)
DELETE 语句与 REFERENCE 约束“FK__Products__Create__1AD3FDA4”冲突。冲突发生在数据库“Foo”、表“dbo.Products”、“CreatedBy”列中。
由于数据库的绝对复杂性,我无法预先删除所有引用,因此我尝试通过级联设置以编程方式添加临时外键以解决它们。但是,对于这个具有多个指向另一个表的外键的特定表,这会导致cycles or multiple cascade paths第二个UpdatedBy更改:
alter table Products add foreign key (CreatedBy) references Users(Id) on delete cascade
alter table Products add foreign key (UpdatedBy) references Users(Id) on delete cascade
Run Code Online (Sandbox Code Playgroud)
在表 'Products' 上引入 FOREIGN KEY 约束 'FK__Products__Update__1DB06A4F' 可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。
我怎样才能delete from Users where在保持参照完整性的同时工作,通过某种方式解决多个级联路径问题或其他方式?
我个人不会这样做(我会预先删除所有引用的数据并手动检查完整性)。请参阅:能否使用 T-SQL 临时禁用外键约束?
引用:
-- disable all constraints
EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"
Run Code Online (Sandbox Code Playgroud)
禁用约束后删除您的数据,但请记住之后再次打开它们!
-- enable all constraints
EXEC sp_msforeachtable @command1="print '?'", @command2="ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"
Run Code Online (Sandbox Code Playgroud)
另请注意,该存储过程sp_msforeachtable未记录在案,可能会在 SQL Server 的未来版本中消失。
如果您不想全面禁用约束(也许您有适用的表的列表),那么只需禁用它们,如上面的代码所示。
ALTER TABLE [Products] NOCHECK CONSTRAINT ALL
DELETE FROM [Users] where Name='Bar'
ALTER TABLE [Products] WITH CHECK CHECK CONSTRAINT ALL
Run Code Online (Sandbox Code Playgroud)
所有功劳都归功于克里斯托夫的回答。请投票!
| 归档时间: |
|
| 查看次数: |
21653 次 |
| 最近记录: |