给定一个包含许多表的数据库,我有一个填充了几个delete和truncate语句的脚本。我的数据库中的每个表都没有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
执行脚本后,我发现正在从脚本中未包含的表中删除数据。
要验证哪些表包含数据,我使用的是在here找到的SO答案中提供的以下查询。
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
我有数据库的备份。接下来我:
我的调查结果如下:数据正从我的删除/截断脚本中未定义的表中删除。
我的问题:鉴于我正在删除或截断数据库中的多个表而不是所有表,如何从未在delete或truncate语句中定义的表中删除数据?
答案 0 :(得分:-1)
如果表包含具有级联引用完整性约束操作值CASCADE
的外键,则可以从未在delete或truncate语句中定义的表中删除数据行。
我发现以下Microsoft文档here有帮助。
级联参照完整性
通过使用级联参照完整性约束,您可以定义操作 数据库引擎在用户尝试删除或更新密钥时采用的 哪些现有的外键指向。以下级联操作可以是 定义。
...
CASCADE
在引用中更新或删除相应的行 在父表中更新或删除该行时的表。级联 如果时间戳列是其中一部分,则无法指定 外键或引用的键。 ON DELETE CASCADE不能 为具有INSTEAD OF DELETE触发器的表指定。 ON UPDATE 无法为具有INSTEAD OF UPDATE的表指定CASCADE 触发。
...
接下来检查是否正在删除表,数据,是否具有外键级联参照完整性约束以及操作值是什么。
方法1: 查询它。我使用的是在here找到的答案中提供的以下查询。
SELECT name, delete_referential_action_desc
FROM sys.foreign_keys
方法2: 在Microsoft SQL Server Management Studio 2016中使用对象资源管理器:
INSERT And UPDATE Specific
部分Delete Rule
值我发现表中的数据正在被删除,它有一个外键级联引用完整性约束,值为Cascade
。
此外,我测试了这是否是实际原因。我将值更新为No Action
,恢复数据库,执行删除/截断脚本,运行'表数据'查询,并发现数据保持不变。