如何从未在删除或截断语句中定义的表中删除数据?

问题描述:

给定一个包含很多表的数据库,我有一个填充了几个delete和truncate语句的脚本。我的数据库中没有针对每个表的删除语句或截断语句。该脚本如下所示(我已经改变名称,缩短了长度):如何从未在删除或截断语句中定义的表中删除数据?

TRUNCATE table db.dbo.table1 
TRUNCATE table db.dbo.table2 
TRUNCATE table db.dbo.table3 

--cannot truncate table because it is being referenced by a FK constraint 
--TRUNCATE table db.dbo.table4 
--TRUNCATE table db.dbo.table5 
--TRUNCATE table db.dbo.table6 
--TRUNCATE table db.dbo.table7 

DELETE FROM db.dbo.table4 
DBCC CHECKIDENT ('db.dbo.table4',RESEED, 0) 
DELETE FROM db.dbo.table5 
DBCC CHECKIDENT ('db.dbo.table5',RESEED, 0) 
DELETE FROM db.dbo.table6 
DBCC CHECKIDENT ('db.dbo.table6',RESEED, 0) 
DELETE FROM db.dbo.table7 
DBCC CHECKIDENT ('db.dbo.table7',RESEED, 0) 
DELETE FROM db.dbo.table8 
DELETE FROM db.dbo.table9 
DELETE FROM db.dbo.table10 
DELETE FROM db.dbo.table11 
DELETE FROM db.dbo.table12 
DELETE FROM db.dbo.table13 
DELETE FROM db.dbo.table14 
DELETE FROM db.dbo.table15 

执行脚本后,我发现这数据是从没有被包含在脚本表中删除。

要验证哪些表包含数据,我使用在SO回答中发现的以下查询here

SELECT 
    t.NAME AS TableName, 
    SUM(p.rows) AS [RowCount] 
FROM 
    sys.tables t 
INNER JOIN  
    sys.indexes i ON t.OBJECT_ID = i.object_id 
INNER JOIN 
    sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id 
WHERE 
    i.index_id <= 1 
GROUP BY 
    t.NAME, i.object_id, i.index_id, i.name 
ORDER BY 
    SUM(p.rows) DESC 

我有数据库的备份。接下来我:

  1. 恢复数据库
  2. 运行“表数据”查询:仔细检查这些数据确实真实存在于不包括在删除表/截断脚本
  3. 执行删除/截断脚本
  4. 运行'表数据'查询

我的发现是这样的:我的delete/truncate脚本中没有定义数据。

我的问题:鉴于我从数据库中的多个表中删除或截断数据库,数据是如何从未在delete或truncate语句中定义的表中删除的?

如果表中包含具有级联参照完整性约束操作值CASCADE的外键,则可以从未在删除或截断语句中定义的表中删除数据行。

我发现以下Microsoft文档位于here有帮助。

级联引用完整性
通过使用级联引用完整性约束,你可以定义动作 ,当用户试图删除或更新一键 其现有的外键指向数据库引擎需要。以下级联操作可以定义为 。
...
CASCADE
当在父表中更新或删除该行时,会在引用 表中更新或删除相应的行。如果时间戳列是 外键或引用键的一部分,则不能指定CASCADE 。 ON DELETE CASCADE不能是 为具有INSTEAD OF DELETE触发器的表指定。 ON UPDATE 对于具有INSTEAD OF UPDATE 触发器的表,不能指定CASCADE。
...

下一个检查,看看表,数据是从,有一个外键级联引用完整性约束,什么动作值将被删除。方法一: 查询。我正在使用在SO回答中发现的以下查询here

SELECT name, delete_referential_action_desc 
FROM sys.foreign_keys 

方法2: 在Microsoft SQL Server Management Studio中2016使用对象资源管理器:

  1. 导航表中的数据被从
  2. 删除扩展表对象
  3. 扩大“键'文件夹
  4. 右键单击一个外键并单击修改
  5. expand INSERT And UPDATE Specific部分位于右下窗格
  6. 识别

我发现桌子上,数据是从,有一个外键级联引用完整性约束与Cascade的值删除Delete Rule值。

此外,我测试了这是否是真正的原因。我更新了值No Action,恢复了数据库,执行了删除/截断脚本,运行了“表数据”查询,并发现数据持久存在。

+1

所以你提出一个问题来回答自己? btw我不downvoting。 –

+0

为了以防万一,考虑一个触发器也会导致删除。 –