我需要从备份中恢复一个表。我的理解是将单个表返回到数据库中的唯一方法是将其复制到临时表中。然后删除旧表并将新表重命名为旧名称。由于主键列是身份列,我的问题出现在这个特定步骤中。该表还有多个外键约束。如何将备份数据库中的一张表复制到原始数据库中,并仍然保留主键标识列和所有外部约束?
这是我当前的脚本尝试:
CREATE TABLE dbo.Incidents_tmp
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[IncidentAction_ID] [int] NULL,
[IncidentCompromise_ID] [int] NULL,
[IncidentDamage_ID] [int] NULL,
[IncidentReportingEntity_ID] [int] NULL,
[IncidentStatus_ID] [int] NULL,
[IncidentType_ID] [int] NULL,
[IncidentID] [varchar](20) NULL,
[Version] [timestamp] NOT NULL,
CONSTRAINT [PK_Incidents_tmp] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
SET IDENTITY_INSERT dbo.Incidents_tmp ON
GO
IF EXISTS ( SELECT *
FROM DB_old.dbo.Incidents )
INSERT INTO DB_new.dbo.Incidents_tmp
(
ID ,
IncidentAction_ID ,
IncidentCompromise_ID ,
IncidentDamage_ID ,
IncidentReportingEntity_ID ,
IncidentStatus_ID ,
IncidentType_ID ,
IncidentID
)
SELECT
ID ,
IncidentAction_ID ,
IncidentCompromise_ID ,
IncidentDamage_ID ,
IncidentReportingEntity_ID ,
IncidentStatus_ID ,
IncidentType_ID ,
IncidentID ,
FROM DB_old.dbo.Incidents TABLOCKX
GO
SET IDENTITY_INSERT DB_new.dbo.Incidents_tmp OFF
GO
ALTER TABLE dbo.IncidentSubject DROP CONSTRAINT
FK_IncidentSubject_Incidents;
ALTER TABLE dbo.IncidentsReportLog DROP CONSTRAINT
FK_IncidentsReportLog_Incidents;
ALTER TABLE dbo.Incidents DROP CONSTRAINT PK_Incidents;
DROP TABLE DB_new.dbo.Incidents
GO
Exec sp_rename 'Incidents_tmp', 'Incidents'
Exec sp_rename 'PK_incidents_tmp', 'PK_Incidents'
ALTER TABLE [dbo].[IncidentSubject] WITH CHECK ADD CONSTRAINT
[FK_IncidentSubject_Incidents] FOREIGN KEY([Incident_ID])
REFERENCES [dbo].[Incidents] ([ID])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[IncidentSubject] CHECK CONSTRAINT
[FK_IncidentSubject_Incidents]
GO
当我尝试重新添加约束时,我收到一条错误消息:
Msg 547, Level 16, State 0, Line 1
The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK_IncidentSubject_Incidents". The conflict occurred in database "DB_new", table "dbo.Incidents", column 'ID'.
编辑:一些额外的信息。该应用程序的用户不小心删除了 175 个事件。不幸的是,她直到两周后才告诉我们,直到将近一个月后才将其发送给我们。用户一直在访问应用程序并进行更改,因此不能选择完整的数据库还原。用户请求仅恢复已删除的事件。我查看了数据库并注意到一个事件表,其中包含当前数据库中缺失的数据以及备份数据库中存在的 175 条记录。希望这能提供一些更好的背景来说明我为什么要尝试只恢复一个事件表。它开始看起来需要恢复其他表。
根据您在问题中提供的信息,我认为您需要将良好的备份(事件的缺失行)恢复到测试数据库中。您需要将备份版本的事件表中缺失的行插入到实际的当前事件表中(确保正确使用SET IDENTITY_INSERT命令)。使用 SET IDENTITY_INSERT ON 允许将显式值插入到表的标识列中,从而允许您插入已删除的行。确保在完成插入后发出 SET IDENTITY_INSERT OFF。您需要对要还原的每个父行的子表进行完全相同的比较和插入,因为在删除父行时会自动删除子表(由于级联删除 FK)。
处理完所有子表后,您应该可以使用
CHECK
.您可能希望在测试服务器上对其进行原型制作。