.net – 如何在SQL Server 2012中的SQLCLR程序集中使用TimeZoneInfo

前端之家收集整理的这篇文章主要介绍了.net – 如何在SQL Server 2012中的SQLCLR程序集中使用TimeZoneInfo前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我想在sql Server 2012中实现时区转换.但是,TimeZoneInfo标有MayLeakOnAbort属性.当调用我定义的sql函数(使用TimeZoneInfo)时,这会导致运行时错误.

错误报告如下

System.Security.HostProtectionException: Attempted to perform an operation that was forbidden by the CLR host.

The protected resources (only available with full trust) were: All

The demanded resources were: MayLeakOnAbort

文档提示我可以使用“SafeHandle”来解决这个泄漏问题,但我不知道如何.

那么,如何在sqlCLR上下文中使用类TimeZoneInfo?

跟进:

我在网站上找到了another question,尽管它处理的是sql 2005,但它规定了一个与2012一起使用的动作.但是,这个解决方案的某些方面并不令人满意.

解决方法

更新的答案

我在原始答案which you can find here中编写了我所说的实用工具.

此外,从sql Server 2016(和Azure sql数据库)开始,您现在可以使用AT TIME ZONE关键字在时区之间进行转换.

原始答案

不幸的是,在sql Server中使用时区没有很好的解决方案.

我严重调查了您链接的问题,以及this one.没有内置时区功能,在sqlCLR中使用TimeZoneInfo需要将程序集注册为“不安全”.这通常是不希望的.

我还使用sqlCLR的Noda Time进行了调查.您可以在this issue中阅读它.由于某些项目在内部缓存的方式,它也必须注册为“不安全”.

最终,对于任何一个项目,问题是无法在sqlCLR中缓存任何内容.您不能以线程安全的方式使用静态变量,并且您不能执行任何线程同步或使用ConcurrentDictionary之类的类. sql希望完全控制程序集的线程模型.只有单线程使用 – 一次性丢弃样式代码才能在“安全”程序集中运行.我在这个问题中深入研究了这一点:Multithreaded caching in SQL CLR

希望最终会有一个可以在sqlCLR中运行的Noda Time构建,但它将是一个不进行任何缓存的特殊构建.因此它不会表现得那么快,但它会在保持安全的同时完成工作.

TimeZoneInfo不太可能改变.因此,除非sql Server团队将时区功能直接引入sql Server(如Oracle和Postgres一样),否则您只有几个选项:

>不要在数据层中尝试时区转换.使用UTC中的datetime或datetime2值,或将datetimeoffset值与任何偏移量一起使用.但是在应用程序层中的时区之间进行所有转换.这是我现在最好的建议.
>将时区的所有数据复制到实际的sql表中,并编写使用该数据的函数.这不是最好的主意,因为数据经常变化,因此表维护可能是一个挑战.此外,准确的功能,包括夏令时变化的所有规则,都具有挑战性.我不知道有任何项目捆绑了漂亮和整洁,但如果有人 – 那么请在评论中让我知道.
>启用xp_regread并直接使用Windows注册表项中的时区数据.更新将为您完成,但您在编写这些功能时仍然面临同样的挑战.启用注册表读取可能与启用不安全的CLR程序集一样具有安全风险.

我正在考虑的另一个想法是编写一个专门用于sql Server的IANA/Olson TZDB解析器和函数.这与上面的选项2类似,但是以可维护的方式完成,并且使用IANA标准数据而不是Windows时区.也许有一天我会接受这个,或者有人会打败我.同样,我不知道有任何当前的项目,但如果有人知道,请在评论中告诉我. (完成 – 见顶部更新)

关于SWITCHOFFSET – 只有在您已经知道目标偏移时才有效.这是成功的一半,也许可能是为什么微软仍然将datetimeoffset标记the docs中的“夏令时”.

原文链接:https://www.f2er.com/mssql/83040.html

猜你在找的MsSQL相关文章