解析SQL Server中datetimeset转换datetime类型问题
作者:潇湘隐者 发布时间:2024-01-15 13:22:34
在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')
来源:https://www.cnblogs.com/kerrycode/archive/2020/12/28/14202017.html


猜你喜欢
- 1、互动流通的活跃度是社区网站的关键,产品设计者大都需要在此猛下药。facebook有利用率最高的minifeed,myspace有“好友的
- INSERT INTO hk_test(username, passwd) VALUES('qmf1', 'qmf1
- 如果有空格就用%20代替,如果有其它字符就用%ASCII代替,如果有汉字等四个字节的字符,就用两个%ASCII来代替。不过有时候我们也需要将
- 1 InnoDB页的概念InnoDB是一个将表中的数据存储在磁盘上的存储引擎,即使我们关闭并重启服务器,数据还是存在。而真正处理数据的过程发
- 经常遇到百度网盘的压缩文件加密了,今天我们就破解它!实现思路上篇文章给大家介绍了爆破密码的思路,感兴趣的朋友可以了解下。其实都大同小异:无非
- reduce() 函数在 python 2 是内置函数, 从python 3 开始移到了 functools 模块。官方文档是这样介绍的re
- 写在最前面:这个我打算分几次写,由于我们通过selenium拿到的图片会很模糊,所以使用Tesseract识别之前要对图片先进行处理。第一步
- 本文实例讲述了Python lambda表达式用法。分享给大家供大家参考,具体如下:lambda表达式,通常是在需要一个函数,但是又不想费神
- 1、数组a第0个元素(二维数组)下的所有子元素(一维数组)的第一列import numpy as npb=np.arange(24)a=b.
- 一、 封装的JS文件 //********************************************************
- 废话不多说啦,直接看代码吧!tf.concatt1 = [[1, 2, 3], [4, 5, 6]]t2 = [[7, 8, 9], [10
- 在输入框里面预设一段提示文字,当焦点在输入框的时候清空这段文字,这在目前来说已经不是什么新鲜事了。淘宝的搜索框就用到了这样一种设计:这种设计
- requests的SSL证书验证1、对于HTTPS默认情况下,启用SSL验证,如果无法验证SSL证书会导致:requests.excepti
- 出错信息为: sys.servers 中找不到服务器 'BBB'。请验证指定的服务器名称是否正确。如果需要,请执行存储过程
- 目录1.随机取小数:2.整数的随机选取:3.随机列表取数,元素打乱:总结1.随机取小数:import randomprint(random.
- 编写思路:把本地文件在客户端通过base64编码以后发送目的地.测试过程中,上传文件过大,导致超时不成功.后来经过改善.把编码分段发送.测试
- tf.app.flags命令行参数解析模块说道命令行参数解析,就不得不提到 python 的 argparse 模块,详情可参考我之前的一篇
- 当服务器必须提供与两个或更多个网络或网络子网的连接时,典型的方案是使用多宿主计算机。此计算机通常位于外围网络(也称为 DMZ、外围安全区域或
- NicEdit的Javascript集成到任何网站在几秒钟内作出的任何元素/区块编辑或转换标准textareas来丰富文本编辑。 How t
- 版本信息:python:3.6mysql:5.7pyMysql:0.7.11################################