【问题标题】:How does one handle Date/Time component Overflow for Conversion to DATETIME2?如何处理转换为 DATETIME2 的日期/时间组件溢出?
【发布时间】:2019-04-26 14:56:45
【问题描述】:

假设您的 SQL Server 数据库中有以下糟糕的数据结构来保存日期时间。

  • 年份(整数)
  • 月(整数)
  • 天(整数)
  • 小时(整数)
  • 分钟(整数)
  • 秒和毫秒(浮点数)

并且您需要保留它,但基于它创建一个计算的 DATETIME2 列,并且在您的一个字段中的数据溢出其实际容量(例如“秒和毫秒”保持 60 或更大)并且您想要将这些字段转换为DATETIME2;你怎么能这样做,以便任何溢出的值级联到更高的日期/时间组件?例如,以下无效的 DateTime 数据将转换如下:

  • 2018-01-01 10:00:60.111 ► 2018-01-01 10:01:00.111
  • 2018-12-31 23:59:61.123 ► 2019-01-01 00:00:01.123
  • 2018-01-01 10:00:120.000 ► 2018-01-01 10:02:00.000

对于我的特殊问题,我看到的数据仅在几秒内溢出,而秒数应仅为 2 位数字,因此它们不会溢出超过 1 分钟,因此仅针对此问题的解决方案就足以满足即时数据的需求。但是,我不喜欢我们必须将这些 int 和 float 字段保留在我们的数据库中以保存日期时间,并且最终希望有一种更防弹的方法来处理任何类型的溢出(为了完整性,也需要下溢)。

我不介意组件字段是否被重新分配以使它们对DATETIME2 有效,或者新的DATETIME2 计算列直接分配转换后的结果并且错误数据保留在组件字段中;只要DATETIME2 的计算列可以持久化。

【问题讨论】:

  • 您可以使用检查约束来确保无效数据不能存储在表中或触发器来验证和规范化数据。 持久计算列可用于使DateTime2 值可用,而无需在每次需要时对其进行组装,并且可以对其进行索引。

标签: tsql datetime2


【解决方案1】:

基本上,我的想法是:

1,先用0作为秒,

2、从SnM中加秒(秒和毫秒)

3,从 SnM 添加毫秒。

注意数据类型转换问题...

试试这个:

select 
dateadd(millisecond, cast(reverse(substring(reverse(cast(cast (SnM as decimal(10,3)) as varchar(50))),1,3)) as int),
dateadd(second, cast(substring(cast(cast (SnM as decimal(10,3)) as varchar(50)),1,charindex('.',cast(cast (SnM as decimal(10,3)) as varchar(50)))-1) as int), 
cast(concat(year,'-',month,'-',day,' ',hour,':',minute,':00') as datetime2))) as newdate
from test

测试结果:

SQL<>Fiddle

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-07
    • 1970-01-01
    • 2022-08-17
    • 1970-01-01
    • 2023-01-01
    • 2020-07-21
    • 1970-01-01
    相关资源
    最近更新 更多