Pourquoi ai-je plusieurs tables d'historique temporel (non associées)?

8

J'ai mis en place un système de preuve de concept doté d'un serveur principal SQL Server 2017.
Le système utilise des tableaux temporels pour enregistrer les configurations des actifs et suivre les changements au fil du temps.
J'ai une table de données qui est liée à la table d'historique, appelons-la dbo.MSSQL_TemporaryHistoryFor_12345678900.

Jusqu'ici tout va bien. J'ai deux problèmes:

Aujourd'hui, j'ai désactivé le contrôle de version sur la table afin de pouvoir ajouter une colonne calculée. Cela a été fait et réactivé sans erreur.

Maintenant, je constate que je ne peux pas interroger les données historiques d'avant le changement. De nouvelles données sont ajoutées à l'historique, mais il n'y a rien d'avance.

En regardant dans SSMS, je peux maintenant voir qu'il y a plusieurs tables d'historique, toutes avec le même nom mais avec un suffixe hexadécimal, par exemple dbo.MSSQL_TemporaryHistoryFor_12345678900_A0B1C2D3. Ils ne sont pas liés sous le tableau de données principal. Ils flottent tout seuls dans la base de données. Lorsque j'ai interrogé sys.tables, ceux-ci ne sont pas affichés en tant que tables d'historique et ne sont pas liés à la table de données principale.

Ces tableaux contiennent les données historiques manquantes.

Les questions que je me pose sont donc:

  • Que représentent ces tableaux supplémentaires?
  • Comment ont-ils été créés?
  • Existe-t-il un moyen de les relier d'une manière ou d'une autre à la chaîne historique principale afin que je puisse récupérer mes rapports historiques?

C'est très frustrant, donc toute aide que vous pourriez fournir serait reçue avec gratitude. Merci.

MrB
la source
1
Il peut être utile de fournir les commandes que vous avez exécutées avant d'entrer dans cet état.
LowlyDBA

Réponses:

8

Vous devez fournir le nom de la table d'historique afin de maintenir la continuité des données lors de l'activation et la désactivation de la version du système. Ce comportement est mentionné dans la documentation d' ALTER TABLE :

Si vous n'utilisez pas l'argument HISTORY_TABLE, le système génère une nouvelle table d'historique correspondant au schéma de la table en cours, crée un lien entre les deux tables et permet au système d'enregistrer l'historique de chaque enregistrement de la table en cours dans le table historique.

Voici une démo. Je vais créer l'exemple de table à partir de la documentation:

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);

Il en résulte une table d'historique nommée MSSQL_TemporalHistoryFor_1253579504. Je vais maintenant désactiver et activer la gestion des versions du système:

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

Et je suis dans votre situation exacte:

entrez la description de l'image ici


Maintenant, je vais tout nettoyer:

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;

Créez ensuite la table avec un nom de table d'historique spécifique:

 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));  

Activez puis désactivez la version du système, mais continuez à spécifier le nom de la table d'historique:

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

Remarque: dans votre situation spécifique, vous devriez pouvoir utiliser cette syntaxe pour "rattacher" une table d'historique perdue à votre table de base

Pas de tables supplémentaires:

entrez la description de l'image ici

À emporter

Spécifiez toujours un nom de table d'historique de manière explicite lors de la création de tables temporelles ou de l'activation du contrôle de version du système.

Les documents MS appellent désormais cela spécifiquement sur la page Arrêt du versionnement du système sur une table temporelle versionnée par le système :

Lorsque vous réactivez la version du système, n'oubliez pas de spécifier l'argument HISTORY_TABLE. Sinon, une nouvelle table d'historique sera créée et associée à la table actuelle. La table historique d'origine existera toujours en tant que table normale, mais ne sera pas associée à la table actuelle.

Josh Darnell
la source