Por que tenho várias tabelas de histórico temporal (não associadas)?


8

Estou configurando um sistema de prova de conceito que possui um back-end do SQL Server 2017.
O sistema usa tabelas temporais para registrar configurações de ativos e rastrear alterações ao longo do tempo.
Eu tenho uma tabela de dados que está vinculada à tabela de histórico, vamos chamá-la de dbo.MSSQL_TemporaryHistoryFor_12345678900.

Por enquanto, tudo bem. Eu tenho dois problemas:

Hoje, desativei o controle de versão na tabela para poder adicionar uma coluna computada. Isso foi feito e ativado novamente sem erros.

Agora, acho que não consigo consultar nenhum dado histórico antes da alteração. Novos dados estão sendo adicionados ao histórico, mas não há nada de antemão.

Olhando para dentro do SSMS, agora posso ver que existem várias tabelas de histórico, todas com o mesmo nome, mas com um sufixo hexadecimal, por exemplo, dbo.MSSQL_TemporaryHistoryFor_12345678900_A0B1C2D3. Eles não estão vinculados abaixo da tabela de dados principal. Eles estão flutuando por conta própria dentro do banco de dados. Quando consultei sys.tables, elas não são mostradas como tabelas de histórico e não estão vinculadas à tabela de dados principal.

Essas tabelas contêm os dados históricos que estão faltando.

As perguntas que tenho são, portanto:

  • O que essas tabelas adicionais representam?
  • Como eles foram criados?
  • Existe alguma maneira de vinculá-los de alguma forma à cadeia principal de histórico para que eu possa recuperar meus relatórios históricos?

É muito frustrante, portanto qualquer ajuda que você puder fornecer será recebida com gratidão. Obrigado.


11
Pode ser útil se você fornecer os comandos executados antes de entrar nesse estado.
LowlyDBA

Respostas:


8

Você precisa fornecer o nome da tabela de histórico para manter a continuidade dos dados ao ativar e desativar a versão do sistema. Esse comportamento é mencionado na documentação para ALTER TABLE :

Se você não usar o argumento HISTORY_TABLE, o sistema gerará uma nova tabela de histórico correspondente ao esquema da tabela atual, criará um link entre as duas tabelas e permitirá que o sistema registre o histórico de cada registro na tabela atual na tabela tabela de histórico.

Aqui está uma demonstração. Vou criar a tabela de exemplo da documentação:

CREATE TABLE dbo.Employee   
(    
  [EmployeeID] int NOT NULL PRIMARY KEY CLUSTERED   
  , [Name] nvarchar(100) NOT NULL  
  , [Position] varchar(100) NOT NULL   
  , [Department] varchar(100) NOT NULL  
  , [Address] nvarchar(1024) NOT NULL  
  , [AnnualSalary] decimal (10,2) NOT NULL  
  , [ValidFrom] datetime2 (2) GENERATED ALWAYS AS ROW START  
  , [ValidTo] datetime2 (2) GENERATED ALWAYS AS ROW END  
  , PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo)  
 )    
 WITH (SYSTEM_VERSIONING = ON);

Isso resulta em uma tabela de histórico denominada MSSQL_TemporalHistoryFor_1253579504. Agora vou desativar e habilitar a versão do sistema:

ALTER TABLE dbo.Employee SET (SYSTEM_VERSIONING = OFF);
ALTER TABLE dbo.Employee SET (SYSTEM_VERSIONING = ON);

E eu estou na sua situação exata:

insira a descrição da imagem aqui


Agora vou limpar tudo:

ALTER TABLE dbo.Employee SET (SYSTEM_VERSIONING = OFF);
DROP TABLE dbo.Employee;
DROP TABLE dbo.MSSQL_TemporalHistoryFor_1253579504;
DROP TABLE dbo.MSSQL_TemporalHistoryFor_1253579504_D0055BB4;

Em seguida, crie a tabela com um nome de tabela de histórico específico:

 CREATE TABLE dbo.Employee   
(    
  [EmployeeID] int NOT NULL PRIMARY KEY CLUSTERED   
  , [Name] nvarchar(100) NOT NULL  
  , [Position] varchar(100) NOT NULL   
  , [Department] varchar(100) NOT NULL  
  , [Address] nvarchar(1024) NOT NULL  
  , [AnnualSalary] decimal (10,2) NOT NULL  
  , [ValidFrom] datetime2 (2) GENERATED ALWAYS AS ROW START  
  , [ValidTo] datetime2 (2) GENERATED ALWAYS AS ROW END  
  , PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo)  
 )    
 WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.EmployeeHistory));  

Em seguida, ative e desative o controle de versão do sistema, mas continue especificando o nome da tabela de histórico:

ALTER TABLE dbo.Employee SET (SYSTEM_VERSIONING = OFF);
ALTER TABLE dbo.Employee SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.EmployeeHistory));

Nota: em sua situação específica, você poderá usar esta sintaxe para "reconectar" uma tabela de histórico perdida à sua tabela base

Sem mesas extras:

insira a descrição da imagem aqui

O takeaway

Sempre especifique um nome de tabela de histórico explicitamente ao criar tabelas temporais ou ativar a versão do sistema.

Os documentos da Microsoft agora chamam isso especificamente na página Parando a versão do sistema em uma tabela temporal com versão do sistema :

Ao ativar a versão do sistema novamente, não se esqueça de especificar o argumento HISTORY_TABLE. Não fazer isso resultará na criação e associação de uma nova tabela de histórico à tabela atual. A tabela de histórico original ainda existirá como uma tabela normal, mas não será associada à tabela atual.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.