项目中由于需求设计,数据库中需要一个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 列不适合作为键使用,尤其是不能作为主键使用。

对数据行(row)的任何更新都会更改 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;
}

SQLSERVER中的timestamp 和 C#中的byte[] 转换的更多相关文章

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

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

  2. sqlserver 中数据导入到mysql中的方法以及注意事项

    数据导入从sql server 到mysql (将数据以文本格式从sqlserver中导出,注意编码格式,再将文本文件导入mysql中): 1.若从slqserver中导出的表中不包含中文采用: bc ...

  3. MySQL 5.6 中的 TIMESTAMP 和 explicit_defaults_for_timestamp 参数

    安装MySQL时,有warning: [root@localhost mysql]# scripts/mysql_install_db --user=mysql Installing MySQL sy ...

  4. 对oracle中date/timestamp的操作

    设置oracle中date的会话格式为 'yyyy-mm-dd hh24:mi:ss' alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss ...

  5. sql中使用timestamp增量抽取数据

    网址:http://www.cnblogs.com/shuaifei/p/4469526.html 最近的项目中需要对上百万级的数据进行增量抽取操作,因此了解了一下TIMESTAMP的应用,特此记录 ...

  6. sql server中的TimeStamp时间戳与UniqueIdentifier数据类型

    TimeStamp SQL Server timestamp 数据类型与时间和日期无关.SQL Server timestamp 是二进制数字,它表明数据库中数据修改发生的相对顺序.实现 timest ...

  7. SqlServer 禁止架构更改的复制中手动修复使发布和订阅中分别增加的字段同步

    原文:SqlServer 禁止架构更改的复制中手动修复使发布和订阅中分别增加的字段同步 由于之前的需要,禁止了复制架构更改,以至在发布中添加一个字段,并不会同步到订阅中,而现在又在订阅中添加了一个同名 ...

  8. TCP/IP协议栈中的TimeStamp选项

    原文转自:http://www.cnblogs.com/lovemyspring/articles/4271716.html TCP应该是以太网协议族中被应用最为广泛的协议之一,这里就聊一聊TCP协议 ...

  9. ES & Filebeat 使用 Pipeline 处理日志中的 @timestamp

    使用 Pipeline 处理日志中的 @timestamp Filebeat 收集的日志发送到 ElasticSearch 后,会默认添加一个 @timestamp 字段作为时间戳用于检索,而日志中的 ...

随机推荐

  1. MONO,原来你是水中月

    什么是MONO? MONO项目是由Ximian发起的,由Miguel de lcaza领导的,一个致力于开创.NET在Linux上使用的开源工程.它包含了一个C#语言的编译器,一个CLR的运行时,和一 ...

  2. Ps6 已具备图层搜索功能

    层多了,找一个层非常考验我们的眼里,不过Photoshop cs6带来了福音,终于有搜索了:

  3. windows如何查看删除记录

    方法 打开组策略中的计算机配置-Windows设置-安全设置-本地策略-审核策略的审核对对像防问, 双击出现的对话框中钩选成功和失败,经过上面的设置,现在就可以设置文件和文件夹的审核了.(注须在NTF ...

  4. Android屏幕尺寸适配注意事项

    1 基本设置 1.1 AndroidManifest.xml设置 在中添加子元素 android:anyDensity="true"时,应用程序安装在不同密度的终端上时,程序会分别 ...

  5. Linux系统getopt使用示例

    #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <stdint.h&g ...

  6. C/C++调用java---JNI常用函数

    DefineClass         jclass  DefineClass(JNIEnv *env, jobject loader,  const jbyte *buf, jsize bufLen ...

  7. Android之旅 自我图示总结四大组件

    最近学完了Android的四大组件的基础知识,自己总结了一个图示,希望自己看到这个图的时候能回忆起相关的知识点,与大家分享!

  8. FormBorderStyle为None的时候如何拖动窗体

    //为DllImport导出命名空间, using System.Runtime.InteropServices; public partial class Form1 : System.Window ...

  9. [Angular-Scaled Web] 6. Navigating between states with ui-router

    There are two ways to naviagting between state: 1. Using $state service, $state.go() 2. Using ui-ser ...

  10. JQuery EasyUI 动态改变表单项的验证守则

    //JQuery EasyUI 动态改变表单项的验证规则 $(document).ready(function(){ $('#FILE_QUALITY').combobox({ onChange:fu ...