项目中由于需求设计,数据库中需要一个timestamp时间戳类型的字段来作为区别数据添加和修改的标识。由于timestamp在SQL SERVER 2005数据库中,不可为空的timestamp类型在语义上等同于binary(8)类型,可为空的 timestamp类型在语义上等同于varbinary(8)类型,这将导致在C#程序中获取到的timestamp类型则变成了byte[]类型。所以如果我们需要从数据库中获取并使用这个时间戳的话就必需经过转换。

我们先建立一张测试表,语句如下:

CREATE TABLE [dbo].[tb_Ts](
[id] [int] IDENTITY(1,1) NOT NULL,
[TS] [timestamp] NULL,
[text] [nvarchar](50) NULL
) ON [PRIMARY]

表名为tb_Ts,只有三个字段id,TS和text。其中TS字段就是我们需要的时间戳字段

SQL Server 中timestamp类型的定义

首先看下timestamp在SQL Server 2005中的定义,该定义摘抄自SQL Server 2005联机丛书(具体详情点击此链接):

timestamp 公开数据库中自动生成的唯一二进制数字的数据类型。timestamp 通常用作给表行加版本戳的机制。 存储大小为 8 个字节。 timestamp 数据类型只是递增的数字,不保留日期或时间。 若要记录日期或时间,请使用 datetime 数据类型。

备注:

每个数据库都有一个计数器,当对数据库中包含 timestamp 列的表执行插入或更新操作时,该计数器值就会增加。 该计数器是数据库时间戳。 这可以跟踪数据库内的相对时间,而不是时钟相关联的实际时间。 一个表只能有一个 timestamp 列。 每次修改或插入包含 timestamp 列的行时,就会在 timestamp 列中插入增量数据库时间戳值。 这一属性使 timestamp 列不适合作为键使用,尤其是不能作为主键使用。 对行的任何更新都会更改 timestamp 值,从而更改键值。 如果该列属于主键,那么旧的键值将无效,进而引用该旧值的外键也将不再有效。 如果该表在动态游标中引用,则所有更新均会更改游标中行的位置。 如果该列属于索引键,则对数据行的所有更新还将导致索引更新。

使用某一行中的 timestamp 列可以很容易地确定该行中的任何值自上次读取以后是否发生了更改。 如果对行进行了更改,就会更新该时间戳值。 如果没有对行进行更改,则该时间戳值将与以前读取该行时的时间戳值一致。 若要返回数据库的当前时间戳值,请使用@@DBTS

Transact-SQL timestamp 数据类型不同于在 SQL-2003 标准中定义的 timestamp 数据类型。 SQL-2003 timestamp 数据类型等同于 Transact-SQL datetime 数据类型。

rowversion 的数据类型为 timestamp 数据类型的同义词,并具有数据类型同义词的行为。 在 DDL 语句,请尽量使用 rowversion 而不是 timestamp。 有关详细信息,请参阅 数据类型同义词 (Transact-SQL)

程序中获取出的timestamp

如何使用SQL语句插入timestamp字段值?

我们从上面的timestamp定义中知道了timestamp这个值一般都是数据库自动添加和修改的,相当于自动增长标识一样(而且执行update修改语句这个字段也会自动更新),所以一般这个字段我们只做查询操作。如果要更新这个字段则会提示这个错误信息:不能更新时间戳列。但是这个字段是可以手动添加的,不过也只能使用DEFALUT字段(default字段为SQL Service数据库的一个默认值),如果传入其他值则会提示错误信息:不能将显式值插入时间戳列。请对列列表使用 INSERT 来排除时间戳列,或将 DEFAULT 插入时间戳列。下面是添加timestamp的SQL语句:

INSERT INTO [tb_Ts]([TS]) VALUES(DEFAULT)

解决数据库中timestamp类型和C#中byte[]类型转换问题

在程序中我们发现,通过ADO.NET获取数据库中timestamp字段值到程序中,结果类型为byte[]。假设在数据库中timestamp的值为0x00000000000007D6,那么获取到.net程序中的值就不是这样了,一把来说会变成byte[]的数组类型。那么我们的解决方式有两种,第一种方式是直接在数据库中将timestamp进行转换,可以转换成十六进制字符串类型或者BIGINT的长整形,这也是我推荐的方法。还有一种是在.NET 程序中使用BitConverter方法进行转换。以下是两种方式的代码:

方法一(在SQL中转换):
SELECT TS
,CAST(TS AS VARBINARY(8)) AS 'timestamp转十六进制字符串'
,CONVERT(BIGINT,TS) AS 'timestamp转bigint类型'
FROM tb_Ts

这样一来我们就可以获取到timestamp的十六进制字符串或者bigint,最终查询出来的结果如下图:

另外要说明的一点是,VARBINARY(8)对应的c# 类型是byte[],所以建议直接转换成bigint类型,否则在C#中还要调用下面的方法


方法二(在程序中转换,调用下面的方法即可):
/// <summary>
/// 将数据库中timespan转换成十六进制字符串
/// </summary>
/// <param name="objTs">从数据库中获取的timespan值</param>
/// <returns>timespan十六进制字符串</returns>
public string ConvertToTimeSpanString(object objTs)
{
byte[] btTsArray=objTs as byte[];
string strTimeSpan = "0x"+ BitConverter.ToString(btTsArray).Replace("-","");
return strTimeSpan;
}

timestamp 字段的更多相关文章

  1. C#更新SQLServer中的TimeStamp字段(时间戳) 防止同时修改一行时覆盖更新

    C#更新SQLServer中的TimeStamp字段(时间戳) 分类: C#2012-10-24 15:10 1878人阅读 评论(0) 收藏 举报 public partial class Form ...

  2. 批量更改int类型的timestamp字段to datetime

    批量更改int类型的timestamp字段to datetime 1.创建datetime字段created_at 2.update 字段 UPDATE table set created_at = ...

  3. mysql timestamp字段定义的

    Cause: java.sql.SQLException: Cannot convert value '2017-07-26 20:40:41.000000' from column 10 to TI ...

  4. mysql关于timestamp字段相关内容

    发现5.6和5.7版本的创建表不一致,从5.6导出数据表创建sql文件,然后导入到5.7表会报错,timestamp不能为空 查看的sql_mode mysql5.0以上支持的三种模式 1. ANSI ...

  5. oracle 将当前系统时间戳插入timestamp字段

    oracle 将当前系统时间戳插入timestamp字段 --insert records 精确到秒:insert into userlogin_his(usrname,logintime) valu ...

  6. mysql 5.5与5.6 timestamp 字段 DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP的区别

    http://www.111cn.net/database/mysql/55392.htm 本文章来给各位同学介绍关于mysql 5.5与5.6 timestamp 字段 DEFAULT CURREN ...

  7. Oracle的timestamp字段更新实验 结论:只有逐条更新才能保证timestamp字段有差别,批量更新只会得到一致的时间,此操作无关时间精度.

    有这么一张表: create table hy_testtime( id number(6,0) not null primary key, name nvarchar2(20) not null, ...

  8. 使用logstash读取MySQL数据传输到es,并且@timestamp字段采用MySQL中的字段时间--建议采用这个

    MySQL中数据样式 ES中数据样式 input { jdbc { jdbc_connection_string => "jdbc:mysql://192.168.0.145:3306 ...

  9. oracle中的timestamp字段的值乱码问题修改

    我的解决方案: 直接新增一个系统变量: key值为:NLS_TIMESTAMP_FORMATvalue的值为:YYYY-MM-DD HH24:MI:SSFF6 其它解决方案: 在登录PLSQL之后,查 ...

随机推荐

  1. CSS3多媒体查询

    CSS2多媒体查询: @media规则在css2中有介绍,针对不同媒体类型(包括显示器,便携设备,电视机,等等)可以定制不同的样式规则. CSS3多媒体查询: CSS3多媒体查询继承了CSS2多媒体类 ...

  2. 【代码笔记】iOS-自定义选择框(高底强弱)

    一,效果图 二,代码. ViewController.h #import <UIKit/UIKit.h> @interface ViewController : UIViewControl ...

  3. 图片圆角显示与手机版文章页面CSS布局

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. Monkey Android app稳定性测试工具之Monkey使用教程

    Monkey Android app稳定性测试工具之Monkey使用教程 by:授客 QQ:1033553122 由于篇幅问题,仅提供百度网盘下载链接: Android app稳定性测试工具之Monk ...

  5. Nodejs搭建wss服务器

    首先使用OpenSSL创建自签名证书: #生成私钥key文件 openssl genrsa > /path/to/private.pem // #通过私钥文件生成CSR证书签名 openssl ...

  6. React Native 二维码扫描组件

    学rn得朋友们,你们知道rn开源项目吗?来吧看这里:http://www.marno.cn/(rn开源项目) React Native学习之路(9) - 注册登录验证的实现 + (用Fetch实现po ...

  7. 构建第一个SpringBoot工程

    学习和使用 SpringBoot 有一段时间了,现在开始陆陆续续会总结归纳 SpringBoot 学习中遇到的相关知识点. SpringBoot 设计目的是用来简化新Spring应用的初始搭建以及开发 ...

  8. excel、xls文件读写操作

    python 常用的excel.xls文件读写操作,有两个模块 xlrd:读 xlwt:写 本次先写一个读的例子: class CaseData(object): def __init__(self, ...

  9. 转:35个让人惊讶的 CSS3 动画效果演示

    本文收集了35个惊人的 CSS3 动画演示,它们将证明 CSS3 Transform 和 Transition 属性的强大能力.CSS 是网页设计非常重要的一部分,随着越来越多的浏览器对 CSS3 支 ...

  10. 【待补充】[Linux] nc

    [nc 是做什么的] [nc怎么用] 查看帮助 nc -help # 查看帮助 nc -help # 监听端口 -l, --listen Bind and listen for incoming co ...