【发布时间】:2021-06-07 03:21:08
【问题描述】:
我将删除与另一个表(子表)有关系的 SQL Server 表(父表)中的数据。
我尝试了基本的删除查询。但它不起作用(我知道它不会)。
DELETE FROM table WHERE ...
返回以下错误
DELETE 语句与 REFERENCE 约束冲突 ...
我需要保留表的架构。我知道我只需要在查询中添加一些单词,我以前做过,但我就是想不起来。
【问题讨论】:
标签: sql-server
我将删除与另一个表(子表)有关系的 SQL Server 表(父表)中的数据。
我尝试了基本的删除查询。但它不起作用(我知道它不会)。
DELETE FROM table WHERE ...
返回以下错误
DELETE 语句与 REFERENCE 约束冲突 ...
我需要保留表的架构。我知道我只需要在查询中添加一些单词,我以前做过,但我就是想不起来。
【问题讨论】:
标签: sql-server
您可以在删除前后禁用和重新启用外键约束:
alter table MyOtherTable nocheck constraint all
delete from MyTable
alter table MyOtherTable check constraint all
【讨论】:
foreign key 引用损坏而失败?
您需要手动删除子项。两个查询的 <condition> 相同。
DELETE FROM child
FROM cTable AS child
INNER JOIN table AS parent ON child.ParentId = parent.ParentId
WHERE <condition>;
DELETE FROM parent
FROM table AS parent
WHERE <condition>;
【讨论】:
如果您希望自动删除,您需要更改架构,使外键约束为ON DELETE CASCADE。
有关详细信息,请参阅MSDN page on Cascading Referential Integrity Constraints。
ETA(在海报澄清后):如果您无法更新架构,则必须先手动删除受影响的子记录。
【讨论】:
在这里,您正在为“子”表添加外键
ALTER TABLE child
ADD FOREIGN KEY (P_Id)
REFERENCES parent(P_Id)
ON DELETE CASCADE
ON UPDATE CASCADE;
之后,如果您像这样对“父”表进行 DELETE 查询
DELETE FROM parent WHERE .....
由于子级通过 DELETE CASCADE 引用了父级,因此“子级”行也将被删除!与“父母”一起。
【讨论】:
ERROR: update or delete on table "question" violates foreign key constraint "answer_question_id_fkey" on table "answer" DETAIL: Key (question_id)=(14) is still referenced from table "answer". SQL state: 23503
因此,您需要 DELETE 冲突表中的相关行或更符合逻辑的 UPDATE 他们的 FOREIGN KEY 列以引用父表中的其他 PRIMARY KEY。
另外,您可能想阅读这篇文章Don’t Delete – Just Don’t
【讨论】:
要从具有父子关系的表中删除数据, 首先你必须通过提及join从子表中删除数据,然后简单地从父表中删除数据,示例如下:
DELETE ChildTable
FROM ChildTable inner join ChildTable on PParentTable.ID=ChildTable.ParentTableID
WHERE <WHERE CONDITION>
DELETE ParentTable
WHERE <WHERE CONDITION>
【讨论】:
有用的脚本,您可以删除数据库所有表中的所有数据, 将 tt 替换为您的数据库名称:
declare @tablename nvarchar(100)
declare c1 cursor for
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_CATALOG='tt' AND TABLE_TYPE='BASE TABLE'
open c1
fetch next from c1 into @tablename
while @@FETCH_STATUS = 0
begin
print @t1
exec('alter table ' + @tablename + ' nocheck constraint all')
exec('delete from ' + @tablename)
exec ('alter table ' + @tablename + ' check constraint all')
fetch next from c1 into @tablename
end
close c1
DEALLOCATE c1
【讨论】:
我使用触发器来删除引用主键的条目。如果不能更改架构,不确定是否可以这样做,但这是 SQLite 中的一个示例:
CREATE TRIGGER remove_parent
BEFORE DELETE ON parent
BEGIN
DELETE FROM
child
WHERE
child.id = OLD.id;
END;
这样每次删除父条目时,子条目也会先被删除。
【讨论】:
SET foreign_key_checks = 0; 从您的表中删除; SET foreign_key_checks = 1;
【讨论】:
在删除 SQL 语句之前和之后设置 FOREIGN_KEY_CHECKS。
SET FOREIGN_KEY_CHECKS = 0;
DELETE FROM table WHERE ...
DELETE FROM table WHERE ...
DELETE FROM table WHERE ...
SET FOREIGN_KEY_CHECKS = 1;
来源:https://alvinalexander.com/blog/post/mysql/drop-mysql-tables-in-any-order-foreign-keys。
【讨论】: