使用SQL生成DateTime.Ticks
在项目中我需要使用到一个随机数(Random Number),该随机数将作为 Hashtable 中的 Key 用于唯一索引数据,所以需要保持单机唯一性。
同时该随机数还需要具备可排序性以便对数据进行排序。
此时,我可以考虑使用随机字符串《C#生成MongoDB中的ObjectId》,这里的 ObjectId 具备单机唯一性和可排序性。
但另一个需求是,我需要该随机数为 int 或 long 类型,以便与依赖的 Service 进行通信,部分取代 TransactionId 或 Token 的职责。
所以,很自然的我就想到了时间。
查看了 MSDN 上关于 DateTime.MinValue 和 DateTime.Ticks 的定义,考虑到我所设计的服务每秒不会产生多于 10000000 的数据,
我决定使用 DateTime.Ticks 作为随机数的起始点,这样就有了下面这段代码。
- public static class UniqueId
- {
- private static long _sequence = DateTime.UtcNow.Ticks;
- public static long Generate()
- {
- return Interlocked.Increment(ref _sequence);
- }
- public static long Sequence
- {
- get
- {
- return _sequence;
- }
- }
- }
业务逻辑中会将 UniqueId 存储到 SQL Server 数据库中,使用 bigint 类型进行存储。
- CREATE TABLE [TableName](
- [UniqueId] [bigint] NOT NULL,
- );
这样,在数据库中,该 UniqueId 即可作为索引,也可进行排序。
现在问题来了,我需要将一个较老的服务升级到新的服务中,做 Date Migration。
老的服务中没有 UniqueId 逻辑和数据,这就需要我在数据迁移时为每条表数据生成该 UniqueId。
显然,SQL Server 不会帮我做这件事,我需要使用 SQL Script 来生成 UniqueId。
DateTime.Ticks 的定义是:
A single tick represents one hundred nanoseconds or one ten-millionth of a second. There are 10,000 ticks in a millisecond.
1 Tick 等于千万分之一秒,或万分之一毫秒。
The value represents the number of 100-nanosecond intervals that have elapsed since 12:00:00 midnight, January 1, 0001, which represents DateTime.MinValue.
DateTime.Ticks 代表着从时间 "00:00:00.0000000, January 1, 0001" 至当前时间的 Tick 总数。
这样,我们就可以根据其原理通过 SQL 来计算其值。
- DECLARE @current_datetime DATETIME;
- DECLARE @days_from_0001_to_1900 BIGINT;
- DECLARE @ticks_per_millisecond BIGINT;
- DECLARE @ticks_per_day BIGINT;
- DECLARE @millisecond_of_time BIGINT;
- DECLARE @ticks_of_days BIGINT;
- DECLARE @ticks_of_time BIGINT;
- DECLARE @ticks BIGINT;
- SET @current_datetime = GETUTCDATE();
- SET @days_from_0001_to_1900 = 693595;
- SET @ticks_per_millisecond = 10000;
- SET @ticks_per_day = 24 * 3600 * 1000 * @ticks_per_millisecond;
- SET @millisecond_of_time =
- DATEPART(MILLISECOND, @current_datetime)
- + (DATEPART(SECOND, @current_datetime)) * 1000
- + (DATEPART(MINUTE, @current_datetime)) * 60000
- + (DATEPART(HOUR, @current_datetime)) * 3600000;
- SET @ticks_of_days = CAST(@days_from_0001_to_1900 + DATEDIFF(DAY, 0, @current_datetime) AS BIGINT) * @ticks_per_day;
- SET @ticks_of_time = @millisecond_of_time * @ticks_per_millisecond;
- SET @ticks = @ticks_of_days + @ticks_of_time;
- SELECT @current_datetime, @ticks
这段 SQL 脚本的运行结果是:
我们通过下面这段 C# 代码来验证结果。
- class Program
- {
- static void Main(string[] args)
- {
- DateTime d1 = new DateTime(, , , , , , , DateTimeKind.Utc);
- DateTime d2 = DateTime.Parse("2014-04-01 02:52:54.153");
- DateTime d3 = DateTime.Parse("2014-04-01 02:52:54.153",
- CultureInfo.CurrentCulture, DateTimeStyles.AdjustToUniversal);
- Console.WriteLine(d1.Ticks);
- Console.WriteLine(d2.Ticks);
- Console.WriteLine(d3.Ticks);
- Console.ReadKey();
- }
- }
瞧,它们的结果一致为 635319175741530000。
使用SQL生成DateTime.Ticks的更多相关文章
- 重构 ORM 中的 Sql 生成
Rafy 领域实体框架设计 - 重构 ORM 中的 Sql 生成 前言 Rafy 领域实体框架作为一个使用领域驱动设计作为指导思想的开发框架,必然要处理领域实体到数据库表之间的映射,即包含了 OR ...
- C#中DateTime.Ticks属性及Unix时间戳转换
1.相关概念 DateTime.Ticks:表示0001 年 1 月 1 日午夜 12:00:00 以来所经历的 100 纳秒数,即Ticks的属性为100纳秒(1Ticks = 0.0001毫秒). ...
- 【转】一道SQL SERVER DateTime的试题
学习过上一篇SQL SERVER DateTime精度的文章后.再来做一道题. IF ('2011-07-31 00:00:00.000' BETWEEN '2011-07-01' and '2011 ...
- c#保存datagridview中的数据时报错 “动态SQL生成失败。找不到关键信息”
ilovejinglei 原文 C#中保存datagridview中的数据时报错"动态SQL生成失败.找不到关键信息" 问题描述 相关代码 using System; us ...
- LINQ To SQL 处理 DateTime?
LINQ To SQL 处理 DateTime? 类型 例子: 搜索栏含有最后扫描时间的日期(DateTime?)与多个其他条件(String) 现在需要写一个查询 : 查询符合最后扫描的日期的查询 ...
- 一条SQL生成数据字典
有个字典表并定期维护,对DBA和开发很重要,终于把他们整合在一起了,看有没问题? 一条SQL生成数据字典,包含所有OPEN用户.表名.字段名.字段序号.字段属性.默认值.是否非空.字段意思.主键标识. ...
- 对于不返回任何键列信息的 selectcommand 不支持 updatecommand 的动态 sql 生成
大家知道,DataSet保存的数据是位于服务器内存里面的原数据库的“副本”.所以用DataSet更新数据的过程就是先对“副本”进行更新,然后 在将“原本”更新,按照我的理解就是把“原本”覆盖掉.具体到 ...
- 查看Linq to Sql生成的sql语句(转)
查看Linq to Sql生成的sql语句 在控制台项目中,比较简单,直接db.Log = Console.Out;就OK了 但是在其他项目中,需要处理如下: StreamWriter sw = ...
- SQL中DateTime转换成Varchar样式
SQL中DateTime转换成Varchar样式语句及查询结果:Select CONVERT(varchar(100), GETDATE(), 0): 05 16 2006 10:57AMSelect ...
随机推荐
- iOS判断数组不为空
用([array count]==0 )来判断是否为空,都是坑,如果array为空的话,执行count就会直接报错,程序崩溃退出. 正确判断NSArray是否为空的方法: if(array != ni ...
- Httpoxy远程代理感染漏洞 [转]
Httpoxy是一个最新曝出的一个CGI程序漏洞,它主要可能威胁到运行在CGI上的PHP,Go,Python和其他代码程序语言. 0×01 什么是httpoxy? 具体来说, httpoxy是一组影 ...
- 深入浅出UML类图(一)
在UML 2.0的13种图形中,类图是使用频率最高的UML图之一.Martin Fowler在其著作<UML Distilled: A Brief Guide to the Standard O ...
- ORACLE 查询一个数据表后通过遍历再插入另一个表中的两种写法
ORACLE 查询一个数据表后通过遍历再插入另一个表中的两种写法 语法 第一种: 通过使用Oracle语句块 --指定文档所有部门都能查看 declare cursor TABLE_DEPT and ...
- UI线程和work线程
UI线程处理消息,比如重绘,响应键盘鼠标等等跟消息有关的处理. 而工作线程一般是你自己写的用来处理数据的,比如操作数据库等等.(work线程)
- JS-concat
var arr1 = [ 1,2,3 ];var arr2 = [ 4,5,6 ];var arr3 = [ 7,8,9 ];alert( arr1.concat( arr2, arr3 ) );
- 用词法分析器Flex过滤日志
每日构造中,我的项目中 Visual Studio 的 MakeFile 后会产生大量信息,如下 Microsoft (R) Visual Studio Version 10.0.40219.1.Co ...
- 领域模型驱动设计(Domain Driven Design)入门概述
软件开发要干什么: 反映真实世界要自动化的业务流程 解决现实问题 领域Domain Domain特指软件关注的领域 在不能充分了解业务领域的情况下是不可能做出一个好的软件 领域建模 领域模型驱动设计 ...
- [UE4]自定义MovementComponent组件
自定义Movement组件 目的:实现自定义轨迹如抛物线,线性,定点等运动方式,作为组件控制绑定对象的运动. 基类:UMovementComponent 过程: 1.创建UCustomMovement ...
- Linux之DNS
DNS服务器配置 一.DNS概述:DNS 是域名系统 (Domain Name System) 的缩写,是一种组织域层次结构的计算机和网络服务命名系统.它的作用是:把域名转换成为网络可以识别的 IP ...