时区和夏令时的MS SQL Server故事(我们需要重新发明轮子吗?)



我正在寻找TSQL和sql作业调度中时间本地化的建议和个人经验(我们使用的是sql Server 2012)。

我遇到了一些情况,我需要在MS SQL Server中对时区和DST支持提供更多支持:

  • 尝试将日期的自动计算列存储在不同的时区中,以便能够对此列的索引进行聚类
  • 还可以更新包含UTC时间的datetime2字段的现有表,以实现以前的目标(例如,PST日期的索引表;没有时间部分)
  • 尝试安排一个sql作业,该作业将在不同时区的特定时间运行(例如,创建仅包含当前PST日期数据的物化视图)

我在网上搜索,发现了这些可能性:

  • A存储带有时区偏移量和夏令时信息的表格,并使用TSQ计算适当的本地化时间(=重新设计需要维护带有时区信息的表格的轮子)
  • B在客户端代码中完全执行本地化,并将结果存储在DB中。此选项需要用于更新现有数据的自定义丢弃应用程序,还需要替换sql作业功能的自定义计划任务应用程序
  • C使用CLR存储过程。我还没有对这个选项进行更深入的研究

还有其他选择吗?任何选项是否有强烈的利弊,可以排除此类选项或其他选项?

不幸的是,您的可能性"A"one_answers"B"是目前仅有的两种可行方法。

选项"A"的缺点是维护成本,而且我还没有看到能够将有效的时区数据库(如IANA数据库)干净地解析为SQL表的东西,这些表的函数可以干净地操作这些表。这应该是可能的,我只是还没有看到。(请注意,它确实适用于MYSQL,Oracle和Postgres也内置了它们,但据我所知,它不适用于MS SQL Server)。

选项"B"是通常的建议,但你会遇到一些无法实现的用例,比如你提到的那些。一个更常见的用例是发出特定时区的"每日报告"。当UTC日期时间必须首先转换到特定时区时,无法实现按日期分组。此外,您可能希望从SSRS或其他报告工具运行这些报告。

选项"C"听起来很有希望,但有一个问题:除非启用"不安全"模式,否则TimeZoneInfo类无法在SQLCLR中操作,这会产生安全和稳定性风险,这对于生产环境来说是不可取的。你可以在这里阅读更多。

我正在研究一个更好的解决方案,那就是将Noda Time修改为可从"安全"模式的SQLCLR环境中使用。这已经在路线图上了,初步测试看起来很有希望。它需要您使用IANA TZDB时区,这可能是一个好主意。完成后,您将有一些简单的用户定义函数来进行时区转换,这些函数依赖于Noda Time程序集的代码和数据。我会在这篇文章准备好后更新它,但我还没有预计到达时间。

更新经过大量测试,我决定最好构建一个基于SQL的解决方案,类似于选项a中描述的解决方案。您现在可以使用我的SQL Server时区支持项目,该项目将IANA时区数据(通过Noda Time)直接导入SQL Server表中。然后,它将这些信息绑定到您可以调用的函数,以便轻松转换。它可靠且可维护,适用于所有SQL Server环境,2008 R2及更高版本,包括Azure SQL DB。

相关内容

  • 没有找到相关文章