带你熟悉SQLServer2016中的System-Versioned Temporal Table 版本由系统控制的临时表
什么是 System-Versioned Temporal Table?
System-Versioned Temporal Table,暂且容我管它叫版本由系统控制的临时表,它是 SQL Server 2016 中的新型用户表,用于保留完整的数据更改历史记录。 它之所以称为版本由系统控制的临时表,是因为每一行的有效期由数据库引擎管理。
每个临时表有两个显式定义的列,其中每个列都有一个 datetime2 数据类型。每当数据修改后,系统将以独占方式使用这些列来记录每行的有效期。
除了这些列以外,该表还包含对使用镜像架构的另一个历史表的引用。 每当更新或删除了临时表中的某行后,系统将使用历史表来自动存储该行的先前版本。
这个临时表的推出,在一定程度上完全可以替代CDC,可用于ETL,追溯数据,审计等。之前CDC能用到的地方这个会更好用且更易维护。另外,以前约定让程序员更新数据时必须更新UpdateTime之类的约定也完全可以交由系统自己控制了。
创建语法:
CREATE TABLE MyTable
(
Id BIGINT IDENTITY(1,1) NOT NULL PRIMARY KEY
,MyCode CHAR(5)
,MyName NVARCHAR(200)
,RecordStartTime DATETIME2 GENERATED ALWAYS AS ROW START NOT NULL
,RecordEndTime DATETIME2 GENERATED ALWAYS AS ROW END NOT NULL
,PERIOD FOR SYSTEM_TIME(RecordStartTime,RecordEndTime)
)
WITH(SYSTEM_VERSIONING = ON);
建好后,在SSMS中是这个样子的:

由于没有指定历史表的名称,历史表自动被命名为MSSQL_TemporalHistoryFor_前缀再加上原始表的objectID.
删除表时必须先执行关闭表的系统版本开关,否则会报错:

ALTER TABLE MyTable SET (SYSTEM_VERSIONING = OFF)
关闭之后,在SSMS中都成了普通表。

删除之后以给定历史表的名字重建(这里历史表的名字指定时必须指定schema,否则会报错):
CREATE TABLE MyTable
(
Id BIGINT IDENTITY(1,1) NOT NULL PRIMARY KEY
,MyCode CHAR(5)
,MyName NVARCHAR(200)
,RecordStartTime DATETIME2 GENERATED ALWAYS AS ROW START NOT NULL
,RecordEndTime DATETIME2 GENERATED ALWAYS AS ROW END NOT NULL
,PERIOD FOR SYSTEM_TIME(RecordStartTime,RecordEndTime)
)
WITH(SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.MyTableHistory));
插入数据:
INSERT INTO [MyTable]([MyCode],[MyName])VALUES('SH001','万剑齐发'),('SH002','ajiangg');
SELECT * FROM [MyTable];

更新/删除数据后的结果:
UPDATE [MyTable] SET MyCode = 'SH003' WHERE ID = 1;
DELETE FROM [MyTable] WHERE ID = 2;
SELECT * FROM [MyTable];
SELECT * FROM [MyTableHistory];

先关闭SYSTEM_VERSIONING,修改历史表名,并再次打开SYSTEM_VERSIONING,即完成了历史表的归档(当然,这样归档的话,归档的那部分数据也就失去了使用FOR SYSTEM_TIME语法查询的能力了):
ALTER TABLE MyTable SET (SYSTEM_VERSIONING = OFF);
EXEC sp_rename 'MyTableHistory', 'MyTableHistory_20170303';
ALTER TABLE MyTable SET (SYSTEM_VERSIONING = ON(HISTORY_TABLE = dbo.MyTableHistory));

追溯历史数据:
SELECT * FROM [MyTable];
SELECT * FROM [MyTableHistory];
SELECT * FROM [MyTable]
FOR SYSTEM_TIME
BETWEEN '2017-03-03 15:43:57.7006650' AND '9999-12-31 23:59:59.9999999'

追溯历史数据查询2(数据存在开始时间小于等于2017-03-03 15:43:57.7006650,且终止时间大于这个时间的Id为2的数据):

关于历史数据的追溯的新条件写法FOR SYSTEM_TIME ****,支持以下几种语法:
| 表达式 | 符合条件的行 | 说明 |
|---|---|---|
| AS OF<date_time> | SysStartTime <= date_time AND SysEndTime > date_time | 返回一个表,其行中包含过去指定时间点的实际(当前)值。 在内部,将在临时表及其历史记录表之间进行联合,然后筛选结果以返回在 <date_time> 参数指定的时间点有效的行中的值。 如果 system_start_time_column_name 值小于或等于 <date_time> 参数值,且 system_end_time_column_name 值大于 <date_time> 参数值,则此行的值被视为有效。 |
| FROM<start_date_time>TO<end_date_time> | SysStartTime < end_date_time AND SysEndTime > start_date_time | 返回一个表,其中包含在指定的时间范围内保持活动状态的所有行版本的值,不管这些版本是在 FROM 自变量的 <start_date_time> 参数之前开始活动,还是在 TO 自变量的 <end_date_time> 参数值之后停止活动。 在内部,将在临时表及其历史记录表之间进行联合,然后筛选结果,以返回在指定时间范围内任意时间保持活动状态的所有行版本的值。 正好在 FROM 终结点定义的下限时间激活的行将包括在内,正好在 TO 终结点定义的上限时间激活的记录将被排除。 |
| BETWEEN<start_date_time>AND<end_date_time> | SysStartTime <= end_date_time AND SysEndTime > start_date_time | 与上面的 FOR SYSTEM_TIME FROM <start_date_time>TO <end_date_time> 描述相同,不过,返回的行表包括在 <end_date_time> 终结点定义的上限时间激活的行。 |
| CONTAINED IN (<start_date_time> , <end_date_time>) | SysStartTime >= start_date_time AND SysEndTime <= end_date_time | 返回一个表,其中包含在 CONTAINED IN 参数的两个日期时间值定义的时间范围内打开和关闭的所有行版本的值。 正好在下限时间激活的记录,或者在上限时间停止活动的行将包括在内。 |
| ALL | 所有行 | 返回属于当前表和历史记录表的行的联合。 |
创建表时,关于GENERATED ALWAYS AS ROW START/END列还有个HIDDEN选项,这在一些我认为的不规范SQL写法中会有些区别(例如Insert时不指定插入的列,查询数据时使用select *等)
另外,不打开SYSTEM_VERSIONING开关的普通表,也能让GENERATED ALWAYS AS ROW START的标识列自动更新更新时间。(例如如下脚本中创建的表,UpdateTime列会被系统自动更新为最后一次更新的时间)
CREATE TABLE MyTable
(
Id BIGINT IDENTITY(1,1) NOT NULL PRIMARY KEY
,MyCode CHAR(5)
,MyName NVARCHAR(200)
,UpdateTime DATETIME2 GENERATED ALWAYS AS ROW START NOT NULL
,RecordEndTime DATETIME2 GENERATED ALWAYS AS ROW END HIDDEN NOT NULL
,PERIOD FOR SYSTEM_TIME(RecordStartTime,RecordEndTime)
);
好了,关于System-Versioned Temporal Table,就介绍到这啦。
本文链接:http://www.cnblogs.com/ajiangg/p/6498873.html
参考链接:https://msdn.microsoft.com/en-us/library/dn935015.aspx
带你熟悉SQLServer2016中的System-Versioned Temporal Table 版本由系统控制的临时表的更多相关文章
- 在.net程序中使用System.Net.Mail来发送邮件
System.Net.Mail是微软自家提供的工具,在.net程序中可以使用该空间中的SmtpClient实例来实现邮件的发送. 使用System.Net.Mail空间与Web.config配置相配合 ...
- ISE 中使用system generate
本文讲解简单的ISE中使用system generate,system generate基本使用规则在此不详细说明可以见博客http://blog.csdn.net/xiabodan/article/ ...
- 带你认识HTML5中的WebSocket
这篇文章主要介绍了带你认识HTML5中的WebSocket,本文讲解了HTML5 中的 WebSocket API 是个什么东东.HTML5 中的 WebSocket API 的用法.带Socket. ...
- 解决未能从程序集xxx中加载类型System.ServiceModel.Activation.HttpModule的问题
在IIS中运行网站时,出现错误: 未能从程序集“System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c ...
- 未能从程序集“System.ServiceModel, Version=3.0.0.0”中加载类型“System.ServiceModel.Activation.HttpModule” 的解决办法
未能从程序集“System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”中加载类型“ ...
- 未能从程序集“System.ServiceModel,xxx”中加载类型“System.ServiceModel.Activation.HttpModule”。
一.平台环境 二.问题描述 未能从程序集“System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561 ...
- Web.config 文件中的 system.webServer
Web.config 文件中的 system.webServer 节用于指定适用于 Web 应用程序的 IIS 7.0 设置.system.WebServer 是 configuration 节的子级 ...
- 配置IIS提示打开目录浏览时的问题:未能从程序集“System.ServiceModel, Version=3.0.0.0”中加载类型“System.ServiceModel.Activation.HttpModule” 的解决办法
错误消息: 未能从程序集“System.ServiceModel, Version=3.0.0.0”中加载类型“System.ServiceModel.Activation.HttpModule” 的 ...
- 【使用WCF,发布服务端浏览报错】未能从程序集“System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089” 中加载类型 “System.ServiceModel.Activation.HttpModule”。
问题: 在WIN7中的IIS服务器中部署WCF服务程序时,通过浏览器访问报出如下错误: 未能从程序集"System.ServiceModel, Version=3.0.0.0, Cultur ...
随机推荐
- MySql安装与使用(linux)
安装 MySQL 注意:此处安装是yum安装为例: MySQL安装 #yum install mysql-server 完后显示如下: MySQL初始化 #service mysqld start 查 ...
- 安装apache 后,找不到服务,解决办法
在命令行进入安装apache的bin目录下,在输入命令:httpd.exe -k install -n Apache版本号 回车即可注意:要在管理员的身份下进入cmd (C:\Windows\SysW ...
- Web渗透:PHP字符编码绕过漏洞总结
其实这东西国内少数黑客早已知道,只不过没有共享公布而已.有些人是不愿共享,宁愿烂在地里,另外的一些则是用来牟利. 该漏洞最早2006年被国外用来讨论数据库字符集设为GBK时,0xbf27本身不是一个有 ...
- Jenkins配置AD域认证
Jenkins配置AD域认证 #检测域控地址ping youad.com指向的IP #如果不是实际域控ip地址,则修改hosts vi /etc/hosts #192.168.100.100替换为实际 ...
- Linux_CentOS-服务器搭建 <五> 补充
O:文件的编码格式 1.文件转码问题 Windows中默认的文件格式是GBK(gb2312),而Linux一般都是UTF-8. 那么先说,如何查看吧.这时候强大的vi说,I can do that.( ...
- Extjs gridPanel可复制配置(转)
ExtJS默认是禁用了文本复制的功能,实际需求中可能需要能够复制,那么如何解决了,我在网上看到了许多解决办法,绝大部分都是从重写CSS样式或者重写gridView代码入手,我遇到这个问题的时候,我想作 ...
- input框限制只能输入正整数、字母、小数、汉字
有时需要限制文本框输入内容的类型,本节分享下正则表达式限制文本框只能输入数字.小数点.英文字母.汉字等代码. 例如,输入大于0的正整数 代码如下: <input onkeyup="if ...
- JWT 从入门到精通
什么是JWT Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点 ...
- [Luogu 3613] 睡觉困难综合征
Description 给定一棵 \(n\) 个点的树,每个点上有位运算 \(opt\) 和一个权值 \(x\),位运算有 &,|,^ 三种. 要求支持: 修改点 \(v\) 的 \(opt\ ...
- Spring之Bean的作用域与生命周期
在前面博客中提到容器启动获得BeanDefinition对象中有一个scope 属性.该属性控制着bean对象的作用域.本章节介绍Bean的作用域及生命周期,了解bean是怎么来的又怎么没的. 一.B ...