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

How is data being removed from tables that are not defined in a delete or truncate statement?

给定一个包含许多 table 的数据库,我有一个脚本,其中填充了几个 delete 和 t运行cate 语句。我的数据库中没有针对每个 table 的删除语句或 t运行cate 语句。脚本如下所示(我更改了名称并缩短了长度):

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

执行脚本后,我发现正在从 table 中删除未包含在脚本中的数据。

为了验证哪些 table 有数据,我正在使用找到的 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. 运行 'table data' 查询:仔细检查 table 中是否确实存在未包含在 delete/truncate 脚本中的数据
  3. 执行delete/truncate脚本
  4. 运行'table data'查询

我的发现是这样的:正在从我的 delete/truncate 脚本中未定义的 table 中删除数据。

我的问题:鉴于我正在从数据库中的多个而不是所有 table 中删除或 t运行cating,如何从 table 中删除数据未在 delete 或 t运行cate 语句中定义?

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

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

Cascading Referential Integrity
By using cascading referential integrity constraints, you can define the actions that the Database Engine takes when a user tries to delete or update a key to which existing foreign keys point. The following cascading actions can be defined.
...
CASCADE
Corresponding rows are updated or deleted in the referencing table when that row is updated or deleted in the parent table. CASCADE cannot be specified if a timestamp column is part of either the foreign key or the referenced key. ON DELETE CASCADE cannot be specified for a table that has an INSTEAD OF DELETE trigger. ON UPDATE CASCADE cannot be specified for tables that have INSTEAD OF UPDATE triggers.
...

接下来检查要从中删除的数据 table 是否具有外键级联参照完整性约束以及操作值是什么。

方法一: 查询它。我正在使用找到的 SO 答案中提供的以下查询 here.

SELECT name, delete_referential_action_desc
FROM sys.foreign_keys

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

  1. 导航到要从中删除数据的 table
  2. 展开table对象
  3. 展开'Keys'文件夹
  4. 右键单击外键并单击修改
  5. 展开位于右下方 window 窗格的 INSERT And UPDATE Specific 部分
  6. 识别Delete Rule价值

我发现正在从中删除数据的 table 具有值为 Cascade 的外键级联引用完整性约束。

此外,我测试了这是否是真正的原因。我将值更新为 No Action,恢复数据库,执行 delete/truncate 脚本, 运行 'table data' 查询,发现数据持久化了。