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中行列转换 Pivot UnPivot
SQL Server中行列转换 Pivot UnPivot PIVOT用于将列值旋转为列名(即行转列),在SQL Server 2000可以用聚合函数配合CASE语句实现 PIVOT的一般语法是:PI ...
- SQL Server中行列转换
典型实例 一.行转列 1.建立表格 ifobject_id('tb')isnotnulldroptabletb go createtabletb(姓名varchar(10),课程varchar(10) ...
- sql server 中 bigint 和 datetime 性能比较
-- 创建表 create table Test_tbl ( ID varchar(40) primary key nonclustered, IntCol int, DateCol datetime ...
- SQL Server中行列转换 Pivot UnPivot
PIVOT用于将列值旋转为列名(即行转列),在SQLServer 2000可以用聚合函数配合CASE语句实现 PIVOT的一般语法是:PIVOT(聚合函数(列)FOR 列 in (-) )AS P 完 ...
- Sql Server Convert函数转换Datetime类型数据
0 Feb 22 2006 4:26PM CONVERT(CHAR(19), CURRENT_TIMESTAMP, 0) 1 02/22/06 CONVERT(CHAR(8), CURRENT_TIM ...
- (转)SQL Server中使用convert进行日期转换
原文链接:http://www.cnblogs.com/weiqt/articles/1826847.html SQL Server中使用convert进行日期转换 一般存入数据库中的时间格式为yyy ...
- SQL Server中提前找到隐式转换提升性能的办法
http://www.cnblogs.com/shanksgao/p/4254942.html 高兄这篇文章很好的谈论了由于数据隐式转换造成执行计划不准确,从而造成了死锁.那如果在事情出现之前 ...
- SQL SERVER中隐式转换的一些细节浅析
其实这是一篇没有技术含量的文章,精通SQL优化的请绕道.这个缘起于在优化一个SQL过程中,同事问了我一个问题,为什么SQL中存在隐式转换,但是执行计划没有变? 我思索了一下,觉得这个问题也有点意思,说 ...
- Sql Server中Float格式转换字符串varchar方法(转)
1.[Sql Server](70) SELECT CONVERT(varchar(100), CAST(@testFloat AS decimal(38,2)))SELECT STR(@testF ...
随机推荐
- fastjson JSONObject简单使用
工作中用的蛮多的最近整理下,概括地说 通过这个工具可以让一个json在json串,JSONObject,java对象之间进行转化 首先我们先写2个bean来构成一个比较复杂的json串: public ...
- 【mq读书笔记】mq消息发送
钩子的注册: DefaultMQProducerImpl#registerSendMessageHook注册钩子处理类,可注册多个. public SendResult sendMessage( fi ...
- 03Python网络编程之单线程服务端
# 对于单线程的服务端,我们借助于zen_utils(我们自己编写好的一些函数)是很容易就实现的.# 导入这个模块import zen_utilsif __name__ == '__main__': ...
- Spring Cloud 学习 (二) Ribbon
负载均衡是指将负载分摊到多个执行单元上,常见的负载均衡有两种方式:一种是独立进程单元,通过负载均衡策略,将请求转发到不同的执行单元上,例如 Ngnix:另一种是将负载均衡逻辑以代码的形式封装到服务消费 ...
- mySQL初学者需要掌握的【数据库与表的基本操作】
本内容会持续更新的哦! 注:"字段"="列","记录''="行" 文章目录 一:数据库的基本操作 二.数据表的基本操作 1.创建与 ...
- 转:Python考核试题及答案
Python测试(总分:120) 选择题(每题2分,共20分) 1.下列哪个语句在Python中是非法的? (B) A.x = y = z = 1 B.x = (y = z + 1) C.x, y = ...
- tesseract-ocr 图片文字识别
本篇记录下python识别图片中的文字 所需的安装配置: 安装库: pip install pytesseract pip install PILLOW 安装 Tesseract-OCR软件: ...
- SASRec 实践
SASRec--2018,ICDM,论文<Self-Attentive Sequential Recommendation> 源代码链接:https://github.com/kang20 ...
- vue项目中扫码枪收款
扫码枪会将扫到的数据带入到获取焦点的输入框中,并且触发输入框的enter回车事件 1.页面上要有一个输入框,并且是获取焦点状态,当然它是隐藏的看不到,我是把宽高设置为0,然后加上回车事件. ...
- 使用IDEA搭建SpringBoot进行增删改查
功能环境:java1.8以上 .IntellJIDEA First: 创建项目,请根据项目图一步一步完成建立. 二.配置数据库 三.创建实体对象建表或对应存在表,根据需要加入相应注解 四.创建应用 ...