Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 如何在SQL Server 2012的SQLCLR程序集中使用TimeZoneInfo_.net_Sql_Sql Server_Timezone_Sqlclr - Fatal编程技术网

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

.net 如何在SQL Server 2012的SQLCLR程序集中使用TimeZoneInfo,.net,sql,sql-server,timezone,sqlclr,.net,Sql,Sql Server,Timezone,Sqlclr,我想在SQL Server 2012中实现时区转换。但是,TimeZoneInfo用MayLeakOnAbort属性标记。这会在调用我定义的SQL函数(使用TimeZoneInfo)时导致运行时错误 错误报告如下 System.Security.HostProtectionException:试图执行CLR主机禁止的操作 受保护的资源(仅在完全信任的情况下可用)为:全部 所需资源为:MayLeakOnAbort 文档提示我可以使用“安全手柄”来解决这个泄漏问题,但我不知道如何解决 那么,如何在S

我想在SQL Server 2012中实现时区转换。但是,TimeZoneInfo用MayLeakOnAbort属性标记。这会在调用我定义的SQL函数(使用TimeZoneInfo)时导致运行时错误

错误报告如下

System.Security.HostProtectionException:试图执行CLR主机禁止的操作

受保护的资源(仅在完全信任的情况下可用)为:全部

所需资源为:MayLeakOnAbort

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

那么,如何在SQLCLR上下文中使用TimeZoneInfo类呢

跟进:

我在这个网站上发现,虽然它处理的是SQL 2005,但它规定了一个适用于2012的操作。不过,该解决方案的某些方面并不令人满意。

更新的答案

我已经编写了我在原始答案中提到的实用程序

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


原始答案

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

我认真调查了你联系到的问题,还有。没有内置的时区函数,在SQLCLR中使用
TimeZoneInfo
需要将程序集注册为“不安全”。这通常是不需要的

我还研究了如何使用SQLCLR。你可以在报纸上读到。由于某些项目在内部缓存的方式,它还必须注册为“不安全”

最终,对于这两个项,问题是无法在SQLCLR中缓存任何内容。您不能以线程安全的方式使用静态变量,也不能执行任何线程同步或使用类,如
concurrentdirectionary
。SQL希望完全控制程序集的线程模型。只有单线程一次性使用样式代码在“安全”程序集中有效。我在这个问题上深入探讨了这一点:

希望最终会有一个在SQLCLR中工作的Noda Time构建,但它将是一个不进行任何缓存的特殊构建。因此,它不会执行得那么快,但它会在安全的情况下完成任务

TimeZoneInfo
不太可能更改。因此,除非SQL Server团队将时区功能直接正确地引入SQL Server(如Oracle和Postgres),否则您只有几个选项:

  • 不要尝试在数据层中进行时区转换。使用UTC中的
    datetime
    datetime2
    值,或将
    datetimeoffset
    值与任何偏移一起使用。但是在应用层中进行时区之间的所有转换。这是我目前最好的推荐

  • 将时区的所有数据复制到实际的SQL表中,并编写处理这些数据的函数。这不是最好的主意,因为数据经常更改,所以表维护可能是一个挑战。此外,要准确地获取功能,包括夏令时更改的所有规则,也是一项挑战。我不知道有任何项目,这捆绑好整洁,但如果有人-那么请让我在评论中知道

  • 启用
    xp\u重新读取
    ,并直接从windows注册表项处理时区数据。更新将为您完成,但您在编写这些函数时仍然面临同样的挑战。无论如何,启用注册表读取可能与启用不安全的CLR程序集一样存在安全风险

我正在考虑的另一个想法是专门为SQLServer编写解析器和函数。这类似于上面的选项2,但以可维护的方式完成,并使用IANA标准数据而不是Windows时区。也许有一天我会做到这一点,或者也许有人会打败我。再说一次,我不知道目前有任何项目可以做到这一点,但如果有人知道,请让我在评论中知道。(完成-请参阅顶部的更新)


关于
开关偏移量
-仅当您已经知道目标偏移量时才起作用。这是战斗的一半,可能也是为什么微软仍然将
datetimeoffset
标记为不支持夏时制的原因。

我知道问题是如何在SQLCLR上下文中使用TimeZoneInfo,但我想我应该补充一点,尽管TimeZoneInfo不受支持(正如@MattJohnson优雅地写道),时区仍然可用,无需使程序集不安全。

您在做什么,SWITCHOFFSET()无法处理?SWITCHOFFSET()要求作者知道所有可能区域的DST转换的所有时区规则。TimeZoneInfo会自动处理该问题。您是在尝试将一个时区的datetimeoffset转换为另一个时区,还是在给定特定datetimeoffset和位置的情况下尝试确定本地日期时间?这是两个完全不同的任务。如果您的问题可以归结为:“数据库服务器旁边墙上的时钟显示了什么”,那么您就有了设计问题。SQL Server从UTC转换为EDT或EST或任何其他已知的静态偏移量都没有问题。遇到问题的地方是要求SQL将UTC转换为本地现行时间。你是说服务器在哪里?你是说客户在哪里?@Anon-大多数时候,当在指定的时区工作时,要求不是像EST或EDT那样以固定的偏移量指定的,而是“东部时间”,或
美国/纽约
。然后,系统将知道夏令时转换点的时间,并根据需要使用正确的偏移。我在这里看到的唯一设计问题是