Eu preciso restaurar uma tabela de um backup. Meu entendimento é que a única maneira de obter uma única tabela de volta ao banco de dados é copiá-la em uma tabela temporária. Em seguida, elimine a tabela antiga e renomeie a nova com o nome antigo. Meu problema vem com esta etapa específica devido à coluna de chave primária ser uma coluna de identidade. A tabela também tem várias restrições de chave estrangeira. Como posso copiar uma tabela do meu banco de dados de backup para o banco de dados original e ainda manter a coluna de identidade da chave primária e todas as restrições externas?
Aqui está minha tentativa de script atual:
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
Quando tento adicionar as restrições de volta, recebo um erro informando:
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'.
EDIT: Algumas informações adicionais. O usuário deste aplicativo excluiu 175 incidentes por acidente. Infelizmente ela não nos contou até duas semanas depois e então não foi encaminhado para nós até quase um mês depois. Os usuários acessam o aplicativo e fazem alterações para que uma restauração completa do banco de dados não seja uma opção. O usuário está solicitando que apenas os incidentes excluídos sejam restaurados. Examinei o banco de dados e notei uma tabela de incidentes com os dados ausentes no banco de dados atual e os 175 registros existentes no banco de dados de backup. Espero que isso forneça um contexto melhor do motivo pelo qual estou tentando restaurar apenas uma única tabela de incidentes. Está começando a parecer que as tabelas adicionais precisam ser restauradas.
Com base nas informações que você forneceu em sua pergunta, acho que você precisará restaurar um bom backup (com as linhas ausentes para incidentes) em um banco de dados de teste. Você precisará inserir na tabela de Incidentes atual real as linhas ausentes da versão de backup da tabela de Incidentes (certificando-se de usar corretamente o SET IDENTITY_INSERTcomando). Usar SET IDENTITY_INSERT ON permite que valores explícitos sejam inseridos na coluna de identidade de uma tabela, permitindo que você insira as linhas excluídas. Certifique-se de emitir o SET IDENTITY_INSERT OFF depois de concluir suas inserções. Você precisará fazer exatamente a mesma comparação e inserir as tabelas filhas para cada uma das linhas pai que está restaurando, pois as filhas foram excluídas automaticamente quando as linhas pai foram excluídas (devido à exclusão em cascata FKs).
Depois de abordar todas as tabelas filhas, você poderá adicionar os FKs novamente com
CHECK
.Você pode querer fazer um protótipo disso em um servidor de teste.