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

时间:2016-07-01 16:20:59

标签: sql-server database sql-delete truncate sql-server-2016

给定一个包含许多表的数据库,我有一个填充了几个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

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

  1. 恢复数据库
  2. 运行'table data'查询:仔细检查数据确实存在于删除/截断脚本中未包含的表中
  3. 执行删除/截断脚本
  4. 运行'表格数据'查询
  5. 我的调查结果如下:数据正从我的删除/截断脚本中未定义的表中删除。

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

1 个答案:

答案 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中使用对象资源管理器:

  1. 导航到正在从
  2. 删除数据的表格
  3. 展开表格对象
  4. 展开'Keys'文件夹
  5. 右键单击外键并单击“修改”
  6. 展开位于右下方窗格中的INSERT And UPDATE Specific部分
  7. 识别Delete Rule
  8. 我发现表中的数据正在被删除,它有一个外键级联引用完整性约束,值为Cascade

    此外,我测试了这是否是实际原因。我将值更新为No Action,恢复数据库,执行删除/截断脚本,运行'表数据'查询,并发现数据保持不变。