System versioned Tables (MS SQL 2016 ->)

A partir de la versión 2016, MS SQL integra el versionado (historial) de datos.

ver también en sqltips

/* SQL Server 2016 introduces support for system-versioned temporal tables as a database feature that brings built-in support for providing information about data stored in the table at any point in time rather than only the data that is correct at the current moment in time. Temporal is a database feature that was introduced in ANSI SQL 2011 and is now supported in SQL Server 2016. */

— 1 Creo una BBDD
— BEGIN TRAN rollback
PRINT ‘1 INICIO ———————————-‘
USE [master]
GO
declare @sql varchar(1000);
IF (EXISTS (SELECT name,* FROM master.dbo.sysdatabases
WHERE (‘[‘ + name + ‘]’ = ‘RMS_TABLAS_TEMPORALES’ OR name =’RMS_TABLAS_TEMPORALES’))) BEGIN
PRINT ‘ ‘ + ‘Existe la BBDD’;
set @sql = ‘USE [RMS_TABLAS_TEMPORALES] ‘; — uso sql dinámico para que no tener error por inexistencia de la BBDD
exec (@sql);
— si existe la tabla, la debo borrar antes que eliminar la bbdd
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = ‘RMS_TABLAS_TEMPORALES’) BEGIN
PRINT ‘ ‘ + ‘existe la tabla temporal’
ALTER TABLE [dbo].[MiTemporal] SET ( SYSTEM_VERSIONING = OFF )
DROP TABLE [dbo].[MiTemporal]
DROP TABLE [dbo].[MiTemporal_Historico]
PRINT ‘ ‘ + ‘TABLA ELIMINADA’;
END
set @sql = ‘DROP DATABASE RMS_TABLAS_TEMPORALES’ ;
USE [master];
exec (@sql);
Print ‘ ‘ + ‘BASE DE DATOS RMS_TABLAS_TEMPORALES’ + ‘ ELIMINADA’;
END

ELSE BEGIN PRINT ‘ ‘ + ‘NO HAY BBDD ‘ + ‘RMS_TABLAS_TEMPORALES’; END;

CREATE DATABASE [RMS_TABLAS_TEMPORALES]
CONTAINMENT = NONE
ON PRIMARY
( NAME = N’RMS_TABLAS_TEMPORALES’, FILENAME = N’C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA\RMS_TABLAS_TEMPORALES.mdf’ , SIZE = 8192KB , FILEGROWTH = 65536KB )
LOG ON
( NAME = N’RMS_TABLAS_TEMPORALES_log’, FILENAME = N’C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA\RMS_TABLAS_TEMPORALES_log.ldf’ , SIZE = 8192KB , FILEGROWTH = 65536KB )

GO
PRINT ‘ ‘ + ‘BASE DE DATOS RMS_TABLAS_TEMPORALES’ + ‘ CREADA’;
declare @sql varchar(1000);
set @sql = ‘USE [RMS_TABLAS_TEMPORALES] ‘; — uso sql dinámico para que no tener error por inexistencia de la BBDD
exec (@sql);
PRINT ‘1 FIN ————————————-‘

USE [RMS_TABLAS_TEMPORALES]

–2. Creo la tabla
PRINT ‘2 INICIO ———————————-‘
CREATE TABLE MiTemporal (
[id] int NOT NULL PRIMARY KEY CLUSTERED,
nombre varchar(100),
una_fecha datetime2 DEFAULT getdate(),

[ValidoDesde] datetime2 (2) GENERATED ALWAYS AS ROW START ,
[ValidoHasta] datetime2 (2) GENERATED ALWAYS AS ROW END,
PERIOD FOR SYSTEM_TIME (ValidoDesde, ValidoHasta)
)
WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.MiTemporal_Historico));
Print ‘ ‘ + ‘TABLA CREADA’
PRINT ‘2 FIN ————————————-‘

— Agrego datos’

INSERT [dbo].[MiTemporal] ([id], [nombre], [una_fecha] –, [ValidoDesde], [ValidoHasta]
) VALUES
(1, N’Roberto’, CAST(N’2017-06-13T16:36:00.7800000′ AS DateTime2)),
(2, N’María’, CAST(N’2017-06-13T16:36:09.7633333′ AS DateTime2)),
(3, N’Juan’, CAST(N’2017-06-13T16:36:16.4500000′ AS DateTime2))
GO
USE [RMS_TABLAS_TEMPORALES]
GO

SELECT [id] ,[nombre] ,[una_fecha] ,[ValidoDesde] ,[ValidoHasta]
FROM [dbo].[MiTemporal]

UPDATE MiTemporal set nombre = ‘Rodolfo’ where nombre = ‘Roberto’;
UPDATE MiTemporal set nombre = ‘Ricardo’ where id = 1;
delete MiTemporal where id = 2;

SELECT [id] ,[nombre] ,[una_fecha] ,[ValidoDesde] ,[ValidoHasta]
FROM [dbo].[MiTemporal]

— hasta aquí, nada nuevo

— Ahora quiero ver a) Los datos modificados
SELECT [id] ,[nombre] ,[una_fecha] ,[ValidoDesde] ,[ValidoHasta]
FROM [dbo].MiTemporal_Historico

— Ahora quiero ver b) como estaban los datos antes de las 3 modificaciones

SELECT [id] ,[nombre] ,[una_fecha] ,[ValidoDesde] ,[ValidoHasta]
FROM [dbo].[MiTemporal]
WHERE 1=1
ORDER BY ID

SELECT [id] ,[nombre] ,[una_fecha] ,[ValidoDesde] ,[ValidoHasta]
FROM [dbo].[MiTemporal]
FOR SYSTEM_TIME AS OF ‘2017-06-13T15:03:29’
WHERE 1=1
ORDER BY ID

— Elimino la tabla
USE [RMS_TABLAS_TEMPORALES]
ALTER TABLE [dbo].[MiTemporal] SET ( SYSTEM_VERSIONING = OFF )
DROP TABLE [dbo].[MiTemporal]
DROP TABLE [dbo].[MiTemporal_Historico]
PRINT ‘TABLA ELIMINADA’;

— SI NO SE QUITA LA bbdd, CERRAR EL ssms Y VOLVER A EJECUTAR
USE [master];
— por último, quito la BBDD
IF (
EXISTS (SELECT name,* FROM master.dbo.sysdatabases
WHERE (‘[‘ + name + ‘]’ = ‘RMS_TABLAS_TEMPORALES’ OR name = ‘RMS_TABLAS_TEMPORALES’))) BEGIN
Declare @sql nvarchar(1000);
set @sql = ‘DROP DATABASE ‘ + ‘RMS_TABLAS_TEMPORALES’ ;

exec (@sql);
Print ‘BBDD ‘ + ‘RMS_TABLAS_TEMPORALES’ + ‘ ELIMINADA’;
END ELSE PRINT ‘NO HAY BBDD ‘ + ‘RMS_TABLAS_TEMPORALES’;
GO
— ALTERNATIVA 2016
–DROP TABLE IF EXISTS RMS_TABLAS_TEMPORALES;