如何删除所有依赖行
How to delete all dependent rows
我有一个 table A 它有主键列 a 并且它是 [=16= 的外键]B table(Table B 有主键 b 和列 a)。Table B 也有一个主键 b,它是 C 的外键 table等等。
现在,如果我想从 Table A 中删除一行,那么它不会允许我,因为它依赖于 table B 并且 table B 依赖于 Table C.So 我必须先从 C 中删除一行,然后是 B,最后是手动删除 A
所以谁能告诉我是否有任何方法可以直接删除而不去每个table并检查它是否有任何依赖关系然后删除
您可以使用级联Cascading Referential Integrity Constraints
更新:
您应该从 Table B 启用 Table A (PK) 的级联参照完整性约束,其中 A 的 ID 是外键,类似地,Table B 的 PK 来自 Table C Where B的ID是外键
非常好的文章BLOG.SQL AUTHORITY
您要查找的字词是 'cascade' - 您需要级联删除。您可以启用它们,如下所述:How do I use cascade delete with SQL Server?
您可以使用级联参照完整性,请参阅此 question。但是,请注意,级联 RI 太多,您可能会在不知不觉中造成很大的损害!
正如其他人已经指出的那样,cascade delete
就是您要查找的内容。在其中一条评论中,您提到您不知道依赖项。这是一个列出依赖项的脚本
SELECT Db_name() referencing_database_name,
Object_name (referencing_id) referencing_entity_name,
Isnull(referenced_schema_name, 'dbo') referenced_schema_name,
referenced_entity_name,
ao.type_desc referenced_entity_type,
Isnull(referenced_database_name, Db_name()) referenced_database_name
FROM sys.sql_expression_dependencies sed
JOIN sys.all_objects ao
ON sed.referenced_entity_name = ao.name
WHERE ao.type_desc = 'USER_TABLE'
自动删除取决于您如何定义 table 之间的关系。
如果您在主 table 中尝试删除行时遇到错误,那是因为您没有在删除关系中指定特殊操作。
我的意思是更改 FK 中的 ON DELETE
和 ON UPDATE
选项。这允许指定当您删除或更新主 table 中的行时子行会发生什么。例如,ON DELETE CASCADE
选项将完全满足您的要求。
例如:
CREATE TABLE Sales.TempSalesReason (
TempID int NOT NULL, Name nvarchar(50
),
CONSTRAINT PK_TempSales PRIMARY KEY NONCLUSTERED (TempID),
CONSTRAINT FK_TempSales_SalesReason FOREIGN KEY (TempID)
REFERENCES Sales.SalesReason (SalesReasonID)
ON DELETE CASCADE
ON UPDATE CASCADE
)
会这样,当您在主 table 中删除或修改一行时,该行也会在子 table.
中修改或删除
相关文档:
如果不允许修改tables,你可以看看EXISTS
运算符。
仅当 EXISTS
return 中的查询至少有 1 个结果时,它才允许您从 table 中删除行。您可以使用它来检查依赖项。
您可以编写 3 个查询:
DELETE C c
WHERE EXISTS (SELECT 1
FROM B b
WHERE c.b = b.b
AND EXISTS (SELECT 1
FROM A a
WHERE a.a = b.a
AND ... ));
DELETE B b
WHERE EXISTS (SELECT 1
FROM A a
WHERE a.a = b.a
AND ...);
DELETE A a
WHERE ...
第一个将处理引用 B
中的记录的 C
中的记录,引用要删除的 A
中的记录。
然后您可以从 B
中删除记录,因为 C
.
中不再有依赖项
最后,您可以使用相同的逻辑从 A
中删除记录。
有一个存储过程“sp_fkeys”,它将为特定 table
提供所有外键
exec sp_fkeys 'My_Table'
因此您可以将输出保存到临时 table,然后在游标中您将删除所有具有任何依赖性的行。如果任何嵌套 table 也有依赖关系,您将执行相同的操作,但对于嵌套 table (递归)
我有一个 table A 它有主键列 a 并且它是 [=16= 的外键]B table(Table B 有主键 b 和列 a)。Table B 也有一个主键 b,它是 C 的外键 table等等。
现在,如果我想从 Table A 中删除一行,那么它不会允许我,因为它依赖于 table B 并且 table B 依赖于 Table C.So 我必须先从 C 中删除一行,然后是 B,最后是手动删除 A
所以谁能告诉我是否有任何方法可以直接删除而不去每个table并检查它是否有任何依赖关系然后删除
您可以使用级联Cascading Referential Integrity Constraints
更新: 您应该从 Table B 启用 Table A (PK) 的级联参照完整性约束,其中 A 的 ID 是外键,类似地,Table B 的 PK 来自 Table C Where B的ID是外键
非常好的文章BLOG.SQL AUTHORITY
您要查找的字词是 'cascade' - 您需要级联删除。您可以启用它们,如下所述:How do I use cascade delete with SQL Server?
您可以使用级联参照完整性,请参阅此 question。但是,请注意,级联 RI 太多,您可能会在不知不觉中造成很大的损害!
正如其他人已经指出的那样,cascade delete
就是您要查找的内容。在其中一条评论中,您提到您不知道依赖项。这是一个列出依赖项的脚本
SELECT Db_name() referencing_database_name,
Object_name (referencing_id) referencing_entity_name,
Isnull(referenced_schema_name, 'dbo') referenced_schema_name,
referenced_entity_name,
ao.type_desc referenced_entity_type,
Isnull(referenced_database_name, Db_name()) referenced_database_name
FROM sys.sql_expression_dependencies sed
JOIN sys.all_objects ao
ON sed.referenced_entity_name = ao.name
WHERE ao.type_desc = 'USER_TABLE'
自动删除取决于您如何定义 table 之间的关系。
如果您在主 table 中尝试删除行时遇到错误,那是因为您没有在删除关系中指定特殊操作。
我的意思是更改 FK 中的 ON DELETE
和 ON UPDATE
选项。这允许指定当您删除或更新主 table 中的行时子行会发生什么。例如,ON DELETE CASCADE
选项将完全满足您的要求。
例如:
CREATE TABLE Sales.TempSalesReason (
TempID int NOT NULL, Name nvarchar(50
),
CONSTRAINT PK_TempSales PRIMARY KEY NONCLUSTERED (TempID),
CONSTRAINT FK_TempSales_SalesReason FOREIGN KEY (TempID)
REFERENCES Sales.SalesReason (SalesReasonID)
ON DELETE CASCADE
ON UPDATE CASCADE
)
会这样,当您在主 table 中删除或修改一行时,该行也会在子 table.
中修改或删除相关文档:
如果不允许修改tables,你可以看看EXISTS
运算符。
仅当 EXISTS
return 中的查询至少有 1 个结果时,它才允许您从 table 中删除行。您可以使用它来检查依赖项。
您可以编写 3 个查询:
DELETE C c
WHERE EXISTS (SELECT 1
FROM B b
WHERE c.b = b.b
AND EXISTS (SELECT 1
FROM A a
WHERE a.a = b.a
AND ... ));
DELETE B b
WHERE EXISTS (SELECT 1
FROM A a
WHERE a.a = b.a
AND ...);
DELETE A a
WHERE ...
第一个将处理引用 B
中的记录的 C
中的记录,引用要删除的 A
中的记录。
然后您可以从 B
中删除记录,因为 C
.
中不再有依赖项
最后,您可以使用相同的逻辑从 A
中删除记录。
有一个存储过程“sp_fkeys”,它将为特定 table
提供所有外键exec sp_fkeys 'My_Table'
因此您可以将输出保存到临时 table,然后在游标中您将删除所有具有任何依赖性的行。如果任何嵌套 table 也有依赖关系,您将执行相同的操作,但对于嵌套 table (递归)