在 SQL 中将 DateTime.Utc.Ticks 类型转换为 DateTime String

问题描述 投票:0回答:1
Type     Stamp                     JobIdText   
104      638488466706836320        UL32443fdf
104      20240416074730            ILF20240416074730277A

当我转换具有 BigInt 的 Stamp 时遇到问题 ( DateTime.Utc.ticks)

我想转换日期时间

例如:638488466706836320 => 预期结果:20240416072013(2024 04 16 ..)

我想更新所有有这样的印章的记录

UPDATE tableName SET Stamp = CASE WHEN ISNUMERIC(Stamp) = 1 THEN CAST(Stamp AS BIGINT) ELSE Stamp END, JobIdText = CASE Type WHEN 100 THEN 'IU' WHEN 101 THEN 'IC' WHEN 102 THEN 'ISF' WHEN 103 THEN 'IODF' WHEN 104 THEN 'ILF' WHEN 105 THEN 'SFM' END + CASE WHEN ISNUMERIC(Stamp) = 1 THEN CAST(CONVERT(BIGINT, CONVERT(VARCHAR(20), DATEADD(MILLISECOND, CAST(Stamp AS BIGINT) / 10000, '19700101'), 120)) AS NVARCHAR(20)) ELSE '' END + LEFT(NEWID(), 4) WHERE JobIdText NOT LIKE '%IU%' AND JobIdText NOT LIKE '%IC%' AND JobIdText NOT LIKE '%ISF%' AND JobIdText NOT LIKE '%IODF%' AND JobIdText NOT LIKE '%ILF%' AND JobIdText NOT LIKE '%SFM%';

错误:不允许从数据类型 datetime 到 bigint 的隐式转换。使用 CONVERT 函数运行此查询。

sql sql-server
1个回答
0
投票
我看到两个问题。首先,您开始使用的值表示自 0001 年 1 月 1 日以来的 100 纳秒刻度数,而不是 1970 年。要使用该开始日期,您需要使用

DATETIME2

 类型进行计算。其次, 
DATEADD()
 函数仅接受 
INT
 值,即位 
BIGINT
。要以所需的精度应用刻度值,您需要将刻度值分成多个组成部分(例如天、秒和纳秒)并按顺序应用每个调整。

另一种方法是将刻度值偏移 599266080000000000,以给出自 1900 年 1 月 1 日以来的刻度数。然而,仍然需要多次

DATEADD()

操作才能达到毫秒(甚至秒)的精度。

最后,如果您的目的是将静止日期/时间值转换为没有标点符号的字符串“yyyymmddhhmmssfff”,您可以将

CONVERT(,,121)

 与一系列 
REPLACE()
 函数结合使用。

以下演示了上述内容的几种变体。

DECLARE @Stamp BIGINT = 638488466706836320 SELECT -- Maximum accuracy DATEADD(day, @Stamp / 864000000000, DATEADD(second, @Stamp % 864000000000 / 10000000, DATEADD(ns, @Stamp % 10000000 * 100, CAST('00010101' AS DATETIME2) ))) AS ConvertedDateTime1, -- Reduced millisecond accuracy DATEADD(day, @Stamp / 864000000000, DATEADD(millisecond, @Stamp % 864000000000 / 10000, CAST('00010101' AS DATETIME2) )) AS ConvertedDateTime2, -- Adjused for use with a 1900-01-01 reference date (1/300 second accuracy) DATEADD(day, (@Stamp - 599266080000000000) / 864000000000, DATEADD(millisecond, (@Stamp - 599266080000000000) % 864000000000 / 10000, CAST('19000101' AS DATETIME) )) AS ConvertedDateTime3, -- Convert to text "yyyy-mm-dd hh:mm:ss" and strip punctuation REPLACE(REPLACE(REPLACE(CONVERT(VARCHAR(23), DATEADD(day, @Stamp / 864000000000, DATEADD(millisecond, @Stamp % 864000000000 / 10000, CAST('00010101' AS DATETIME2) )), 120), '-', ''), ' ', ''), ':', '') AS ConvertedDateTime4p % 864000000000 / 10000000, DATEADD(ns, @Stamp % 10000000 * 100, CAST('00010101' AS DATETIME2) ))) AS ConvertedDateTime1, -- Reduced millisecond accuracy DATEADD(day, @Stamp / 864000000000, DATEADD(millisecond, @Stamp % 864000000000 / 10000, CAST('00010101' AS DATETIME2) )) AS ConvertedDateTime2, -- Adjused for use with a 1900-01-01 reference date (1/300 second accuracy) DATEADD(day, (@Stamp - 599266080000000000) / 864000000000, DATEADD(millisecond, (@Stamp - 599266080000000000) % 864000000000 / 10000, CAST('19000101' AS DATETIME) )) AS ConvertedDateTime3, -- Convert to text "yyyy-mm-dd hh:mm:ss.fff" and strip punctuation REPLACE(REPLACE(REPLACE(REPLACE(CONVERT(VARCHAR(23), DATEADD(day, @Stamp / 864000000000, DATEADD(millisecond, @Stamp % 864000000000 / 10000, CAST('00010101' AS DATETIME2) )), 121), '-', ''), ' ', ''), ':', ''), '.', '') AS ConvertedDateTime4
结果:

转换日期时间1转换日期时间2转换日期时间3转换日期时间42024-04-16 06:44:30.68363202024-04-16 06:44:30.68300002024-04-16 06:44:30.68320240416064430
请参阅

this db<>fiddle 进行演示。

© www.soinside.com 2019 - 2024. All rights reserved.