如何处理日期/时间分量溢出以转换为DATETIME2?

时间:2019-04-26 14:56:46

标签: tsql datetime2

假设您在SQL Server数据库中具有以下恶劣数据结构来保存日期时间。

  • 年份(int)
  • 月份(int)
  • 日期(整数)
  • 小时(int)
  • 分钟(int)
  • 第二毫秒(浮动)

您需要保留它,但要基于它创建一个计算的DATETIME2列,并且在您其中一个字段的数据中其实际容量溢出(例如,“ Second and Millsecond”保持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字段保留在数据库中以保存Date Times,并且最终希望使用一种更加防弹的方法来处理任何类型的上溢(为了完整性也要考虑下溢)。

我不在乎是否重新分配了组件字段以使其对DATETIME2有效,还是直接为新的DATETIME2计算列分配了转换结果,而不良数据仍保留在组件字段;只要DATETIME2的计算列可以保留。

1 个答案:

答案 0 :(得分: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