如何在 SQL Server 中运行 DELETE 语句之前确定要在相关/其他表中删除的记录

Posted

技术标签:

【中文标题】如何在 SQL Server 中运行 DELETE 语句之前确定要在相关/其他表中删除的记录【英文标题】:How to determine records to be deleted in related/other tables before running DELETE statement in SQL Server 【发布时间】:2021-11-25 05:32:53 【问题描述】:

我对 SQL Server 比较陌生。我想从表中删除一些记录。我想运行语句:

DELETE Table1 
WHERE COLUMN1 = 7

因此,在运行查询之前,我运行了以下查询:

SELECT * 
FROM Table1 
WHERE COLUMN1 = 7

查询结果为 3 行。

我在 SSMS 中运行了原始的 DELETE 查询,结果显示:

324 ROWS affected
0 ROWS affected
3 ROWS affected

我猜在某处有某种触发器或外键导致此语句删除其他表中的额外 324 行。我恢复了数据库以解决问题。

问题是:在我在 SSMS 中执行之前,有没有办法根据我的 DELETE 语句显示/列出要删除的任何/所有记录?

【问题讨论】:

使用begin tran,运行您的查询,然后使用commitrollback。如果您有触发器(我们不知道您是否不知道),您可能希望删除行,因为它很可能保持参照完整性。 begin tran/rollback 结合获取实际(未估计)查询计划,应该会告诉你一切 hi @Stu 如何在语句中间删除行? @Charlieface 我如何获得实际的查询计划? docs.microsoft.com/en-us/sql/relational-databases/performance/… 【参考方案1】:

要运行数据修改查询并确信它具有预期和预期的结果,请执行以下操作。

总是在你的陈述前加上begin tran

确保您检索到实际的执行计划 - (CTRL + M) 或查询菜单 > 包括实际执行计划。

在运行查询之前,运行set statistics io on

运行您的查询,确保您已包含begin tran

检查执行计划选项卡,该选项卡将显示查询中涉及的每个表。

查看 IO 统计信息的 messages 选项卡,它会列出每个表以及针对每个表执行的 IO 量。

如果一切正常,运行commit tran,或者如果你想取消查询运行rollback

请注意,如果您在生产系统上工作,您的事务可能会阻止其他查询,直到您 commitrollback

【讨论】:

【参考方案2】:

Utilized ON DELETE CASCADE 这将指定删除父数据时删除子数据。

下面是一个示例,当我们使用级联作为删除规则创建第二个外键时,上面的删除命令通过删除子表“States”中的记录成功运行,这反过来又删除了第二个子表“Cities”中的记录。

CREATE TABLE Countries

(CountryID INT PRIMARY KEY,
CountryName VARCHAR(50),
CountryCode VARCHAR(3))


CREATE TABLE States

(StateID INT PRIMARY KEY,
StateName VARCHAR(50),
StateCode VARCHAR(3),
CountryID INT)

GO


CREATE TABLE Cities
(CityID INT,
CityName varchar(50),
StateID INT)
GO

INSERT INTO Countries VALUES (1,'United States','USA')

INSERT INTO Countries VALUES (2,'United Kingdom','UK')

INSERT INTO States VALUES (1,'Texas','TX',1)
INSERT INTO States VALUES (2,'Arizona','AZ',1)

INSERT INTO Cities VALUES(1,'Texas City',1)
INSERT INTO Cities values (1,'Phoenix',2)

GO


ALTER TABLE [dbo].[States]  WITH CHECK ADD  CONSTRAINT 
[FK_States_Countries] FOREIGN KEY([CountryID])
REFERENCES [dbo].[Countries] ([CountryID])
ON DELETE CASCADE
GO


ALTER TABLE [dbo].[Cities]  WITH CHECK ADD  CONSTRAINT 
[FK_Cities_States] FOREIGN KEY([StateID])
REFERENCES [dbo].[States] ([StateID])
ON DELETE CASCADE
GO

DELETE FROM Countries where CountryID =1

【讨论】:

以上是关于如何在 SQL Server 中运行 DELETE 语句之前确定要在相关/其他表中删除的记录的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 2005 触发器 - 如何安全地确定是由 UPDATE 还是 DELETE 触发?

追踪SQL Server执行delete操作时候锁的申请与释放过程

sql server insert 与 delete 三百万级数据量时速度极慢,有10分钟左右,求高手如何解决

sql server中如何快速批量删除表里的百万条记录!直接用delete top(50000)还是有点慢...

如何使用 VB.NET 配置 DataAdapter 以使用 Sql Server 存储过程执行 Select、Update、Insert 和 Delete 命令?

SQL Server Profiler 2008 怎么追踪特定种类语句如 insert,update,delete,能指定某个数据追踪吗