环境:
- window10
- sqlserver2014
- vs2022
- .net core 3.1
参考:
微软官方文档:rowversion (Transact-SQL)
在sqlsever中 timestamp
和rowversion
是同义词,它和 ISO 标准中定义的 timestamp 数据类型表现不同。
在sqlserver中,timestamp
的作用是给每行的数据加上版本标志,但这个标志和时间没有任何关系,可以将它看成是byte[8]
数组并且是数据库全局自增的。
因为timestamp
的取值是数据库全局自增的,所以它是多表共享的。可以通过 @@DBTS
查看当前的版本号。
1. 实验timestamp:
准备表:
create table test2(
id int identity(1,1) primary key,
name varchar(50),
flag timestamp
)
查看当前数据库的版本:
向这个表插入三行数据:
insert into test2(name) values('小名'),('小红'),('小刚')
查看表数据及DBTS:
可以看到,timestamp列的值是自增的,并且和全局的DBTS保持一致。
再修改表两条数据:
update test2 set name=name+'2' where id=1
update test2 set name=name+'2' where id=2
再查看表数据及全局DBTS:
和预料的一样,版本号增加到了2097
,再进行删除操作(删除操作不会导致DBTS自增):
delete from test2 where id=1
然后,再观察表数据和全局DBTS:
可以看到,删除数据并不会导致DBTS自增,为了进一步验证,再插入一条数据:
insert into test2(name) values('小兰')
再观察表数据和全局DBTS:
可以看到,新插入数据又导致全局DBTS自增了。
2. timestamp和rowversion是同义词
虽然它们两个是同义词,但行为上并不完全相同。
当ddl创建表时,可以声明timestamp
列类型而不指定表名,此时数据库自动生成列名timestamp
,而rowversion
则必须指定表名。
3. timestamp不对外开放写入
数据库控制timestamp列值的生成和更新,我们无法手动插入和更新,如下:
4. 在映射到c#数据类型
由于从ado.net 中读取后为一个8字节的数组,所以我们需要使用byte[]
来接受,如果我们准备使用long
的话就需要自行转换,或者读取时使用sql:select flag,cast(flag as bigint) from test2