¿Por qué tengo varias tablas de historial temporal (no asociadas)?

8

He estado configurando un sistema de prueba de concepto que tiene un servidor SQL Server 2017.
El sistema utiliza tablas temporales para registrar configuraciones de activos y rastrear cambios a lo largo del tiempo.
Tengo una tabla de datos que está vinculada a la tabla de historial, llamémosla dbo.MSSQL_TemporaryHistoryFor_12345678900.

Hasta aquí todo bien. Tengo dos problemas:

Hoy apagué el control de versiones en la tabla para poder agregar una columna calculada. Esto se hizo y se volvió a encender sin errores.

Ahora encuentro que no puedo consultar ningún dato histórico anterior al cambio. Se están agregando nuevos datos al historial, pero no hay nada de antemano.

Mirando dentro de SSMS, ahora puedo ver que hay varias tablas de historial, todas con el mismo nombre pero con un sufijo hexadecimal, por ejemplo, dbo.MSSQL_TemporaryHistoryFor_12345678900_A0B1C2D3. No están vinculados debajo de la tabla de datos principal. Simplemente están flotando por su cuenta dentro de la base de datos. Cuando pregunté a sys.tables, estos no se muestran como tablas de historial y no están vinculados a la tabla de datos principal.

Estas tablas contienen los datos históricos que faltan.

Las preguntas que tengo son por lo tanto:

  • ¿Qué representan estas tablas adicionales?
  • ¿Cómo fueron creados?
  • ¿Hay alguna forma de volver a vincularlos de alguna manera a la cadena principal de la historia para que pueda recuperar mis informes históricos?

Es muy frustrante, por lo que cualquier ayuda que pueda brindar sería agradecida. Gracias.

MrB
fuente
1
Puede ser útil si proporciona los comandos que ejecutó antes de entrar en este estado.
LowlyDBA

Respuestas:

8

Usted necesita proporcionar el nombre de la tabla de historia con el fin de mantener la continuidad de los datos cuando se enciende el sistema de versiones de vez en cuando. Este comportamiento se menciona en la documentación de ALTER TABLE :

Si no utiliza el argumento HISTORY_TABLE, el sistema genera una nueva tabla de historial que coincide con el esquema de la tabla actual, crea un enlace entre las dos tablas y permite que el sistema registre el historial de cada registro en la tabla actual en el tabla de historia

Aquí hay una demostración. Crearé la tabla de ejemplo a partir de la documentación:

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

Esto da como resultado una tabla de historial denominada MSSQL_TemporalHistoryFor_1253579504. Ahora deshabilitaré y habilitaré el control de versiones del sistema:

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

Y estoy en tu situación exacta:

ingrese la descripción de la imagen aquí


Ahora lo limpiaré todo:

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;

Luego cree la tabla con un nombre de tabla de historial 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));  

Luego, active y desactive la versión del sistema, pero continúe especificando el nombre de la tabla de historial:

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

Nota: en su situación específica, debería poder usar esta sintaxis para "volver a conectar" una tabla de historial perdida a su tabla base

No hay mesas extra:

ingrese la descripción de la imagen aquí

La comida para llevar

Siempre especifique un nombre de tabla de historial explícitamente al crear tablas temporales o habilitar el control de versiones del sistema.

Los documentos de MS ahora lo mencionan específicamente en la página Detención del control de versiones del sistema en una página de tabla temporal versionada por el sistema :

Cuando vuelva a activar la versión del sistema, no olvide especificar el argumento HISTORY_TABLE. De lo contrario, se creará una nueva tabla de historial y se asociará con la tabla actual. La tabla de historial original seguirá existiendo como una tabla normal, pero no se asociará con la tabla actual.

Josh Darnell
fuente