Nous souhaitons mettre en œuvre des tables temporelles dans SQL Server 2016. Nous créons une datawarehouse et développons des tables de dimensions de type 2 de type 2.
Pour le début, nous voulons que cela dépend de la date de transaction et non du temps getdat actuel. Nous reproduisons une histoire de transactions. Exemple ci-dessous, le client dispose d'une salle de sport ou d'un statut bancaire et passe d'inactif, actif ou en attente de la date de transaction.
Nous avons actuellement cela.
CREATE TABLE dbo.Department
(
CustomerId int primary key,
MembershipStatus int,
TransactionDate datetime
);
Nous aimerions créer une table comme celle-ci.
CREATE TABLE dbo.DepartmentHistory
(
CustomerId int primary key,
MembershipStatus int,
TransactionDate datetime,
BeginDatetime datetime,
EndDatettime datetime
);
Exemple d'utilisation serait:
+ ------------- + -------- + ----------- + --------- + [.____] | CustomerId | Statut | BEGINDE | Enddate | + ------------ + -------- + ----------- + ------------- + ------------- + ------------- + ------------- + ------------- + ------------- + ------------- + ------------- + ------------- + ------------- + ------------- + ------------- + ------------- + ------------- + ------- - + [.____] | 1 | P | 3/5/2018 | Null | + ------------ + -------- + ----------- + ------------- + ------------- + ------------- + ------------- + ------------- + ------------- + ------------- + -------- - +
[.____] + ------------- + -------- + ----------- + --------------- - + [.____] | CustomerId | Statut | BEGINDE | Enddate | + ------------ + -------- + ----------- + ------------- + ------------- + ------------- + ------------- + ------------- + ------------- + ------------- + ------------- + ------------- + ------------- + ------------- + ------------- + ------------- + ------------- + ------- --- + | 1 | P | 3/5/2018 | 14/12/2018 | [.____] | 1 | Un | 4/21/2018 | Null | + ------------ + -------- + ----------- + ------------- + ------------- + ------------- + ------------- + ------------- + ------------- + ------------- + -------- --- +
Tables temporelles sont Système - Versed1, donc le seul moyen de " Définir manuellement" L'horodatage d'une ligne d'historique donnée consiste à modifier le temps d'exploitation au moment où la ligne est modifiée qui ... vous ne voulez probablement pas faire.
Si vous voulez " Définir manuellement" Time limites sur une table d'historique de sorte qu'elle prend en charge Syntaxe de requête temporelle , vous pouvez le faire en appliquant manuellement une table temporelle sur le dessus de vos données existantes. Ceci est un peu délicat et nécessite que les données sous-jacentes se conforment aux règles de la version de l'historique temporel. Google est parsemé de divers articles de blog sur ce dos lorsque des tables temporelles ont été introduites; Puisque je n'ai pas joué avec ce cas d'utilisation exacte depuis un moment, je vais désormais créer des liens arbitrairement à cet exemple qui semble prometteur .
N'oubliez pas qu'une table temporelle vers la version système est en fait deux tables - A "MAINTENANT" Table and a "Historique" Table spéré ensemble. ..
create table dbo.b_now (
i int not null primary key
,info varchar(10)
,start_dt datetime2 generated always as row start
,end_dt datetime2 generated always as row end
,period for system_time (start_dt, end_dt)
) with (system_versioning = on (history_table = dbo.b_history));
go
insert b_now (i,info)
values
(1,'AAA')
,(2,'BBB');
go
update b_now set info = 'XXX' where i = 1
go
select * from b_history
select * from b_now
go
Notez que pendant que b_now
semble être la "table de base" et prend en charge la syntaxe temporelle - il n'est qu'un objet distinct. Supprimer la liaison de la version système entre les objets renforce ceci.
Garder cela à l'esprit - et rappelez-vous que nous pouvons changer SYSTEM_VERSIONING
à partir de ON
à _ OFF
et retour ON
.à à nouveau, nous pouvons dire que SQL Server d'appliquer arbitrairement (et ignorer arbitrairement) les règles de versement du système à une paire d'objets arbitraires si longtemps. comme...
Mais je veux exemple de code!
Oui, je pensais que tu pouvais - alors essayez ceci ...
drop table if exists a_now ,a_history;
go
create table a_now (
i int not null primary key
,info varchar(10)
,start_dt datetime2 not null
,end_dt datetime2 not null
-- you'll want this CHECK later...
check (end_dt = convert(datetime2,'9999-12-31 23:59:59.9999999'))
);
go
create table a_history (
i int not null
,info varchar(10)
,start_dt datetime2 not null
,end_dt datetime2 not null
);
go
declare @end_of_time datetime2 = '9999-12-31 23:59:59.9999999';
insert a_now values
(1,'XXX','2017-01-01',@end_of_time)
,(2,'BBB','2017-01-01',@end_of_time)
insert a_history values
(1,'AAA','2016-01-01','2017-01-01');
go
select * from a_now
select * from a_history
... a l'air beaucoup comme b_now
et b_history
, n'est-ce pas? Dommage que ce n'est pas une table système appropriée ...
alter table a_now
add period for system_time (start_dt, end_dt);
go
alter table a_now
set (system_versioning = on (history_table = dbo.a_history));
go
Attendre wut ...? Vous pouvez même plonger une vue sur la table "MAINTENANT" pour cacher votre abus des conventions de dénomination.
create or alter view a
as
select * from a_now
go
select *
from a
for system_time as of '2016-06-01'
Ok oui ... mais comment puis-je ajouter de nouvelles lignes M. Smarty Pants?
Très soigneusement ... c'est comme ça.
alter table a_now
set (system_versioning = off);
alter table a_now
drop period for system_time;
go
declare @end_of_time datetime2 = '9999-12-31 23:59:59.9999999';
insert a_now values
(3,'CCC','2018-01-01',@end_of_time);
update a_now set
start_dt = '2018-01-01'
,info = 'YYYY'
where i = 1;
insert a_history
values
(1,'XXX','2017-01-01','2018-01-01')
alter table a_now
add period for system_time (start_dt, end_dt);
go
alter table a_now
set (system_versioning = on (history_table = dbo.a_history));
go
select * from a for system_time as of '2017-06-01'
Je laisse le lecteur (vous) pour terminer le INSERT
/UPDATE
/DELETE
logique et pertinent DROP
/re -SET
Vérification du système dans un module récupéable.
1. N.B. Ceci est allongé avec la syntaxe le period for SYSTEM_time
Dans le DDL requis pour la création d'une table temporelle