Temporal tables

Navigation:  APPENDICI >

Temporal tables

Previous pageReturn to chapter overviewNext page

Le Temporal Tables, o SYSTEM-VERSIONED Temporal Tables, permettono di mantenere una cronologia completa delle modifiche effettuate sui dati in essa presenti, tramite un aggiornamento automatico da sistema.

 

warning

L'utilizzo delle Temporal Tables necessita che i Database di IrionEDM abbiano installato SQL Server 2016.

 

 

Sono contraddistinte da

un PERIODO di validità, definito da due campi DATAFrom, DataTo di tipo datetime2;

da un campo Period, definito come FOR SYSTEM_TIME sui due campi definiti nel punto precedente.

 

Ogni Temporal Table è implementata tramite due tabelle fisiche (devono essere conformi in schema)

Main (o current) Table: contiene le versioni attuali (effettive) delle righe;

History Table: contiene la cronologia.

 

La definizione di una Temporal Table in IrionEDM avviene principalmente in due diversi modi:

creando la tabella direttamente come System_Versioned. Lo script creerà sia la Main sia la History Table già con il System_Versioned attivo.

convertendo una tabella già esistente, considerata come Main, alla quale verrà associata una altrettanto già esistente tabella, considerata come History.

 

Per creare la tabella in modalità System_Versioning ON, occorre utilizzare un comune script T-SQL di CREATE TABLE con in aggiunta i campi:

ValidFrom  / ValidTo

Period

 

ValidFrom / ValidTo devono avere le seguenti caratteristiche:

datatype DATETIME2

GENERATED ALWAYS AS ROW START / END

NOT NULL

HIDDEN (opzionale)

Se i campi sono già presenti in tabella, occorre effettuare su di essi una operazione di CONVERT di tipo Datetime2.

 

La clausola Hidden è opzionale. La dichiarazione esplicita permette di nascondere le nuove colonne a meno dell'esplicito richiamo nella query di interrogazione.

Period si definisce utilizzando la clausola FOR SYSTEM_TIME (ValidFrom , ValidTo)

 

Occorre, inoltre, inserire in fondo allo script la clausola:

 

WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = <schema_name>.<nome_temptable>History));

 

di cui:

Schema_name: corrisponde all'identificativo univoco del databox in cui si vuole creare la tabella;

HistoryTable: indica la tabella di cronologia in cui si vogliono storicizzare le modifiche apportate sulla Main Table

 

Lo Schema_name viene recuperato tramite la funzione di IrionEDM SCHEMA_NAME() richiamata all’interno di un DataBoxLink.

La clausola ALTER TABLE SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = <schema_name>.<nome_temptable>History)) non può essere utilizzata in IrionEDM perchè non si possiedono particolari permessi.

 

warning

La Main Table deve avere sempre una Primary Key,dunque i campi in chiave devono essere NOT NULL.

 

 

Per convertire una tabella già esistente in una Temporal Table occorre:

Effettuare una operazione di ALTER TABLE – ADD nella Main Table per aggiungere, se non già presenti, i campi ValidFrom e ValidTo e il PERIOD. I campi dovrano necessariamente avere tutte le caratteristiche descritte in precedenza;

Effettuare una operazione di ALTER TABLE – ADD nella History Table per aggiungere i campi ValidFrom e ValidTo definiti con un default e NOT NULL;

Utilizzare la seguente Stored Procedure [idq].[Changesystemversioningstatus] per abilitare il SYSTEM_VERSIONING:

 

EXEC [idq].[Changesystemversioningstatus]

     @tableName = '<nome_table>',

     @logTableName = '<nome_temptableHistory>',

     @enable = 1

 

warning

La [idq].[Changesystemversioningstatus] è una Stored Procedure che agisce su Temporal Table già create.

 

La stored procedure riceve, in input, i seguenti parametri:

1. @tableName varchar(256): nome della Temporal (Main) Table;

2. @logTableName varchar(256): nome della History Table;

3. @enable bit: attiva (1) o disattiva (0) il SYSTEM_VERSIONING;

4. @retentionPeriod varchar(128): indica per quanto tempo si vuole mantenere la storicizzazione di un dato;

5. @dataConsistencyCheck bit: attiva (1) o disattiva (0) il controllo di consistenza tra la Main e la History Table.

 

info

I parametri @retentionPeriod e @dataConsistencyCheck sono opzionali.

Di defaut, @retentionPeriod è illimitato, @dataConsistencyCheck è attivo.

 

Per effettuare l’operazione opposta, ossia convertire una Temporal Table in una non dotata di controllo di versione, occorre:

Disabilitare il SYSTEM_VERSIONING richiamando la Stored Procedure [idq].[Changesystemversioningstatus] con parametro @enable bit = 0;

Droppare la colonna PERIOD FOR SYSTEM_TIME;

Droppare, se necessario, anche le colonne di Periodo.

 

warning

Prima di poter effettuare la conversione da Temporal Table in Main Table è necessario verificare se vi è qualche vincolo di default sulle colonne Required o il SYSTEM_VERSIONING attivo sulla Temporal Table. Nel caso ci fossero, occorre eliminare i vincoli e spegnere il SYSTEM_VERSIONING prima di fare DROP delle colonne.

 

Le seguenti operazioni sono consentite su Temporal Table:

INSERT: per inserire nuovi record nelle Temporal Table possono essere utilizzati i comuni script T-SQL di INSERT e l’utente può omettere di valorizzare i campi del PERIOD (ValidFrom, ValidTo);

UPDATE: l’operazione di aggiornamento di record avviene secondo i comuni script T-SQL di UPDATE Table;

DELETE: l’operazione di cancellazione di record avviene secondo i comuni script T-SQL di DELETE Table;

TRUNCATE: l’operazione non è permessa se il SYSTEM_VERSIONIG è attivo;

MERGE: in questo caso l’intera operazione si comporta come se venissero eseguiti tre statement (INSERT, UPDATE, DELETE) in base all’azione specificata;

SELECT: l’operazione di interrogazione di una tabella avviene secondo i comuni script T-SQL di SELECT ma con l’aggiunta della clausola FOR SYSTEM_TIME, che permette di escludere le righe con periodo di validità pari a 0 (ValidFrom = ValidTo).

 

Per la INSERT, il sistema li setta AUTOMATICAMENTE come:

ValidFrom: con l’inizio della transazione, basato su un sistama di clock.

ValidTo: con il valore di DEFAULT  “9999-12-31T23:59:59.00000”

 

info

Il clock utilizzato dal sistema per aggiornare le colonne del PERIOD a seguito di cambiamenti utilizza il fuso orario UTC. La conversione al fuso corretto deve avvenire a carico dell’utente. Alcune funzioni utili al recupero dei fusi orari e alla convesione sono AT TIME ZONE '<nome_timezone>'o DATEPART(YEAR|MONTH|DAY|HOUR|MINUTE|SECOND|TZOFFSET, AT TIME ZONE '<nome_timezone>')

 

Per la UPDATE, il sistema storicizza i valori precedentemente presenti della riga nella History Table e setta:

ValidTo (History Table): con l’inizio delle transazione corrente,  basato su un sistema di clock, determinando il nuovo periodo di validità della riga;

ValidFrom (Main Table): con l’inizio delle transazione corrente,  basato su un sistema di clock, determinando il nuovo periodo di validità della riga;

ValidTo (Main Table): con il valore di DEFAULT “9999-12-31T23:59:59.00000”.

 

Per la DELETE, il sistema storicizza i valori precedentemente presenti della riga nella History Table e setta:

DataTo (History Table): con l’inizio delle transazione corrente,  basato su un sistema di clock;

nella Main Table la riga viene rimossa.

 

La clausola FOR SYSTEM_TIME, usata nella SELECT viene accompagnata da da cinque sotto-clausole temporali:

ALL: se occorre eseguire query sui dati correnti e cronologici senza restrizioni;

AS OF:  se occorre ricostruire lo stato dei dati esistente in un momento specifico nel passato;

BETWEEN ... END, FROM, CONTAINED IN: se occorre recuperare tutte le modifiche avvenute per una riga specifica nella tabella corrente.

 

ex

ESEMPIO DI SCRIPT DI CREAZIONE DI UNA TEMPORAL TABLE

Per creare una Temporal Table con l'opzione SYSTEM_VERSIONING attiva, si può procedere nel modo seguente:

 

CREATE TABLE <nome_temptable>
(  
    [name1] int NOT NULL 
  , [name2] nvarchar(100) NOT NULL
  , [name3] int NOT NULL 
  , [ValidFrom] datetime2 (0) GENERATED ALWAYS AS ROW START HIDDEN NOT NULL
  , [ValidTo] datetime2 (0) GENERATED ALWAYS AS ROW END HIDDEN NOT NULL
  , PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo)

  , CONSTRAINT pk_<nome_temptable> PRIMARY KEY (name1, name2, name3)
 )  
 WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = <schema_name>.<nome_temptable>History))