sqlserverdatetime时区(解析SQL Server中datetimeset转换datetime类型问题)
sqlserverdatetime时区
解析SQL Server中datetimeset转换datetime类型问题在SQL Server中,数据类型datetimeoffset转换为datetime类型或datetime2类型时需要特别注意,有可能一不小心你可能会碰到下面这种情况。下面我们构造一个简单案例,模拟一下你们可能遇到的情况。
CREATE TABLE TEST ( ID INT IDENTITY(1,1) ,CREATE_TIME DATETIME ,CONSTRAINT PK_TEST PRIMARY KEY(ID) ); GO INSERT INTO TEST(CREATE_TIME) SELECT '2020-10-03 11:10:36' UNION ALL SELECT '2020-10-03 11:11:36' UNION ALL SELECT '2020-10-03 11:12:36' UNION ALL SELECT '2020-10-03 11:13:36'; DECLARE @p1 DATETIMEOFFSET; SET @p1='2020-10-03 11:12:36.9200000 +08:00' SELECT * FROM dbo.TEST WHERE CREATE_TIME <=@p1;
如下截图所示,你会发现这个查询SQL查不到任何记录。相信以前对数据类型datetimeoffset不太熟悉的人会对这个现象一脸懵逼......
那么我们通过下面例子来给你简单介绍一下,datetimeoffset通过不同方式转换为datetime有啥区别,具体脚本如下:
DECLARE @p1 DATETIMEOFFSET; DECLARE @p2 DATETIME; DECLARE @p3 DATETIME2; SET @p1='2020-10-03 11:10:36.9200000 +08:00' SET @p2=@p1; SET @p3=@p1; SELECT @p1 AS '@p1' ,@p2 AS '@p2' ,CAST(@p1 AS DATETIME) AS 'datetimeoffset_cast_datetime' ,CONVERT(DATETIME, @p1, 1) AS 'datetimeoffset_convert_datetime'
如下截图所示,通过CONVERT函数将datetiemoffset转换为datetime,你会发现上面这种方式丢失了时区信息,它将datetimeoffset转换为了UTC时间了。官方文档介绍:转换到datetime 时,会复制日期和时间值,时区被截断。
注意:datetiemoffset转换为datetime2也是同样的情况,这里不做赘述了。
所以,最开始,我们构造的案例中,出现那种现象是因为@p1和CREATE_TIME比较时,发生了隐式转换,datetiemoffset转换为datetime,而且转换过程中时区丢失了,此时的SQL实际等价于CREATE_TIME <='2020-10-03 03:10:36.920'了,那么怎么解决这个问题,如果在不改变数据类型的情况下,有什么解决方案解决这个问题呢?
方案1:使用CAST转换函数。
DECLARE @p1 DATETIMEOFFSET; SET @p1='2020-10-03 11:12:36.9200000 +08:00' SELECT * FROM dbo.TEST WHERE CREATE_TIME <=CAST(@p1 AS DATETIME)
方案2:CONVERT函数中指定date_style为0 ,可以保留时区信息。
DECLARE @p1 DATETIMEOFFSET; SET @p1='2020-10-03 11:12:36.9200000 +08:00' SELECT * FROM dbo.TEST WHERE CREATE_TIME <=CONVERT(DATETIME, @p1, 0)
下面例子演示对比,有兴趣的话,自行执行SQL后对比观察
DECLARE @p1 DATETIMEOFFSET; DECLARE @p2 DATETIME; DECLARE @p3 DATETIME2; SET @p1='2020-10-03 11:10:36.9200000 +08:00' SET @p2=@p1; SET @p3=@p1; SELECT @p1 AS '@p1' ,@p2 AS '@p2' ,CAST(@p1 AS DATETIME) AS 'datetimeoffset_cast_datetime' ,CONVERT(DATETIME, @p1, 0) AS 'datetimeoffset_convert_datetime' ,CONVERT(DATETIME, @p1, 1) AS 'datetimeoffset_convert_datetime1'
方案3:SQL Server 2016(13.x)或以后的版本可以使用下面方案。
注意之前的SQL Server版本不支持这种写法.
DECLARE @p1 DATETIMEOFFSET; SET @p1='2020-10-03 11:12:36.9200000 +08:00' SELECT * FROM dbo.TEST WHERE CREATE_TIME <= CONVERT(DATETIME, @p1 AT TIME ZONE 'UTC' AT TIME ZONE 'China Standard Time')
到此这篇关于SQL Server中datetimeset转换datetime类型问题浅析的文章就介绍到这了,更多相关SQL Server中datetimeset转换datetime类型内容请搜索开心学习网以前的文章或继续浏览下面的相关文章希望大家以后多多支持开心学习网!
- mysql全套优化(Mysql优化神器推荐)
- mysql有什么索引(MySQL 普通索引和唯一索引的区别详解)
- mysql查询语法总结(MySQL全面瓦解之查询的过滤条件详解)
- docker部署tomcat(Docker安装Tomcat、MySQL和Redis的步骤详解)
- mysql提高分页效率(MySQL优化教程之超大分页查询)
- mysql事务特性和隔离级别(Mysql事务特性和级别原理解析)
- MongoDB命令与SQL语法对比
- python怎么操作mysql(详解Python的数据库操作pymysql)
- sqlserver语句创建窗口布局(SQL Server 2012 开窗函数)
- sql server 2019 资源不足不可信(SQL Server异常代码处理的深入讲解)
- mysql索引知识点总结(MySQL 8.0 之索引跳跃扫描Index Skip Scan)
- mysql创建存储过程的代码(MySQL修改存储过程的详细步骤)
- mysql 使用小结(Mysql Online DDL的使用详解)
- mysql权限管理详解(Mysql 用户权限管理实现)
- mysql支持存储表情(MySQL如何插入Emoji表情)
- SQL中patindex的用法
- 八月再见 愿你岁月不扰,余生静好(八月再见愿你岁月不扰)
- 赏读 八月再见,九月你好(赏读八月再见九月你好)
- 散文 八月再见,九月,我在风中等你(散文八月再见九月)
- 8月再见 9月你好(8月再见)
- 魔兽世界 设计师爆料,原始版本并无PVP,跨阵营属于返璞归真(魔兽世界设计师爆料)
- 吐槽完《弧光大作战》之后,我们和设计师聊了聊魔兽首款手游的立项初衷和未来(吐槽完弧光大作战之后)
热门推荐
- js判断是否为手机访问
- 微信小程序映射设置(微信小程序虚拟列表的实现示例)
- C# using关键字的用法
- 阿里云申请ssl证书要好久(阿里云部署SSL证书详解)
- apache怎么安装服务(apache后缀名支持 让apache支持apk ipk下载的方法)
- reactnative零基础入门到项目实战(用React Native制作一个简单的游戏引擎)
- 云数据库navicat连不上(Navicat Premium15连接云服务器中的数据库问题及遇到坑)
- php扩展安装示例(php扩展开发入门demo示例)
- js return false的作用
- laravel查询构建器原理和使用(阿里对象存储OSS在laravel框架中的使用方法)