假设有一个包含主键的主表,另一个表包含该主表的外键。因此,如果我们删除主表行,它也会删除子表。
如何撰写此查询?
答案 0 :(得分:20)
从您的问题来看,我认为您可以安全地假设CASCADING DELETES已开启 在这种情况下所需要的只是
DELETE FROM MainTable
WHERE PrimaryKey = ???
您的数据库引擎将负责删除相应的引用记录。
答案 1 :(得分:19)
首先,作为一次性数据清理练习,删除孤立的行,例如
DELETE
FROM ReferencingTable
WHERE NOT EXISTS (
SELECT *
FROM MainTable AS T1
WHERE T1.pk_col_1 = ReferencingTable.pk_col_1
);
其次,作为一次性模式更改练习,将ON DELETE CASCADE
引用操作添加到引用表上的外键,例如
ALTER TABLE ReferencingTable DROP
CONSTRAINT fk__ReferencingTable__MainTable;
ALTER TABLE ReferencingTable ADD
CONSTRAINT fk__ReferencingTable__MainTable
FOREIGN KEY (pk_col_1)
REFERENCES MainTable (pk_col_1)
ON DELETE CASCADE;
然后,永久地,当引用的行被删除时,引用表中的行将被自动删除。
答案 2 :(得分:8)
您可以使用delete cascade选项更改外键约束,如下所示。这将删除与主表行相关的chind表行。
ALTER TABLE MasterTable
ADD CONSTRAINT fk_xyz
FOREIGN KEY (xyz)
REFERENCES ChildTable (xyz) ON DELETE CASCADE
答案 3 :(得分:4)
如果要删除多行,并且不想更改表的结构 你可以使用光标。 1 - 首先需要选择要删除的行(在游标中) 2 - 然后对于光标中的每一行,删除引用行,然后删除它自己的行。
例如:
--id is primary key of MainTable
declare @id int
set @id = 1
declare theMain cursor for select FK from MainTable where MainID = @id
declare @fk_Id int
open theMain
fetch next from theMain into @fk_Id
while @@fetch_status=0
begin
--fkid is the foreign key
--Must delete from Main Table first then child.
delete from MainTable where fkid = @fk_Id
delete from ReferencingTable where fkid = @fk_Id
fetch next from theMain into @fk_Id
end
close theMain
deallocate theMain
希望是有用的
答案 4 :(得分:-2)
需要将外键选项设置为删除级联 ... 在包含外键列的表中....需要在创建表时设置或稍后使用ALTER表
添加