简体   繁体   English

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

[英]How does one use TimeZoneInfo in a SQLCLR assembly in SQL Server 2012

I want to implement time zone conversion within SQL Server 2012. However, TimeZoneInfo is marked with the MayLeakOnAbort attribute. 我想在SQL Server 2012中实现时区转换。但是,TimeZoneInfo标有MayLeakOnAbort属性。 This causes a runtime error when the SQL function I defined (which uses TimeZoneInfo) is invoked. 当调用我定义的SQL函数(使用TimeZoneInfo)时,这会导致运行时错误。

The error is reported as follows 报告错误如下

System.Security.HostProtectionException: Attempted to perform an operation that was forbidden by the CLR host. System.Security.HostProtectionException:尝试执行CLR主机禁止的操作。

The protected resources (only available with full trust) were: All 受保护的资源(仅在完全信任的情况下可用)是:全部

The demanded resources were: MayLeakOnAbort 需求的资源是:MayLeakOnAbort

Documentation hints that I can use "SafeHandle" to get around this leakage issue but I do not see how. 文档暗示我可以使用“SafeHandle”来解决这个泄漏问题,但我不知道如何。

So, how does one use the class TimeZoneInfo in a SQLCLR context? 那么,如何在SQLCLR上下文中使用类TimeZoneInfo?

Follow Up: 跟进:

I have found another question here on the site which, though it deals with SQL 2005, prescribes an action which works with 2012. There are aspects of this solution, though, which are unsatisfying. 我在网站上发现了另一个问题 ,虽然它涉及SQL 2005,但它规定了一个适用于2012的行动。但是,这个解决方案的某些方面并不令人满意。

Updated Answer 更新的答案

I've written the utility I spoke about in the original answer, which you can find here . 我在原始答案中写了我所说的实用程序, 你可以在这里找到

Also, as of SQL Server 2016 (and Azure SQL Database), you can now use the AT TIME ZONE keyword to convert between time zones. 此外,从SQL Server 2016(和Azure SQL数据库)开始,您现在可以使用AT TIME ZONE关键字在时区之间进行转换。


Original Answer 原始答案

Unfortunately, there is no great solution for working with time zones in SQL Server. 不幸的是,在SQL Server中使用时区没有很好的解决方案。

I investigated heavily the issue you linked, along with this one also. 我大量调查了你所链接的问题,以及这个问题。 There are no built-in time zone functions, and any use of TimeZoneInfo in SQLCLR requires the assembly to be registered as "unsafe". 没有内置时区功能,在SQLCLR中使用TimeZoneInfo需要将程序集注册为“不安全”。 This is usually not desired. 这通常是不希望的。

I also investigated using Noda Time from SQLCLR. 我还调查了使用SQLCLR的Noda Time You can read about it in this issue . 您可以在此问题中阅读相关内容。 It also had to be registered as "unsafe" because of the way certain items are cached internally. 由于某些项目在内部缓存的方式,它也必须注册为“不安全”。

Ultimately, with either item, the problem is that there is no way to cache anything in SQLCLR. 最终,对于任一项,问题在于无法在SQLCLR中缓存任何内容。 You can't use static variables in a thread-safe manner, and you cant do any thread synchronization or use classes like ConcurrentDictionary . 您不能以线程安全的方式使用静态变量,并且您不能执行任何线程同步或使用ConcurrentDictionary类的类。 SQL wants to have full control of the threading model of the assembly. SQL希望完全控制程序集的线程模型。 Only single-threaded use-once-and-throw-away style code works in "safe" assemblies. 只有单线程使用 - 一次性丢弃样式代码才能在“安全”程序集中运行。 I dug deep into this in this question: Multithreaded caching in SQL CLR 我在这个问题中深入研究了这个问题: SQL CLR中的多线程缓存

Hopefully, there will eventually be a build of Noda Time that will work in SQLCLR, but it will be a special build that doesn't do any caching. 希望最终会有一个Noda Time的版本可以在SQLCLR中运行,但它将是一个不进行任何缓存的特殊版本。 So it won't perform as quickly, but it will get the job done while still being safe. 因此它不会表现得那么快,但它会在保持安全的同时完成工作。

TimeZoneInfo isn't likely to change. TimeZoneInfo不太可能改变。 So unless the SQL Server team ever brings time zone functions directly into SQL Server properly (like Oracle and Postgres do), then you've only got a few options: 因此,除非SQL Server团队将时区功能直接引入SQL Server(如Oracle和Postgres一样),否则您只有几个选项:

  • Don't attempt time zone conversions in the data layer. 请勿尝试在数据层中进行时区转换。 Work with datetime or datetime2 values in UTC, or use datetimeoffset values with any offset. 使用UTC中的datetimedatetime2值,或将datetimeoffset值与任何偏移量一起使用。 But do all conversions between time zones in the application layer. 但是,在应用程序层中的时区之间进行所有转换。 This is my best recommendation for now. 这是我现在最好的建议。

  • Copy all of the data for the time zones into actual SQL tables, and write functions that work with that data. 将时区的所有数据复制到实际的SQL表中,并编写使用该数据的函数。 This isn't the best idea, because the data changes often so table maintenance can be a challenge. 这不是最好的主意,因为数据经常变化,因此表维护可能是一个挑战。 Also getting the functions accurate, including all of the rules of daylight saving changes, can be challenging. 此外,准确的功能,包括夏令时变化的所有规则,都具有挑战性。 I am not aware of any project that has this bundled up nice and neat, but if anyone is - then please let me know in comments. 我不知道有任何项目捆绑了漂亮和整洁,但如果有人 - 那么请在评论中让我知道。

  • Enable xp_regread and work with the timezone data directly from the windows registry keys. 启用xp_regread并直接从Windows注册表项使用时区数据。 Updates would be done for you, but you still have the same challenges in writing these functions. 更新将为您完成,但您在编写这些功能时仍然面临同样的挑战。 And enabling registry reads might be just as much of a security risk as enabling unsafe CLR assemblies anyway. 启用注册表读取可能与启用不安全的CLR程序集一样具有安全风险。

Another idea I am considering is to write an IANA/Olson TZDB parser and functions specifically for SQL Server. 我正在考虑的另一个想法是编写IANA / Olson TZDB解析器并专门为SQL Server运行。 This would be similar to option 2 above, but done in a maintainable way, and with IANA standard data instead of Windows time zones. 这与上面的选项2类似,但是以可维护的方式完成,并且使用IANA标准数据而不是Windows时区。 Maybe I'll get to this someday, or maybe someone will beat me to it. 也许有一天我会接受这个,或者有人会打败我。 Again, I am not aware of any current project that does this, but if someone knows of one, please let me know in comments. 同样,我不知道有任何当前的项目,但如果有人知道,请在评论中告诉我。 ( done - see update at top ) 完成 - 见顶部更新

Regarding SWITCHOFFSET - that only works when you already know the target offset. 关于SWITCHOFFSET - 只有在您已经知道目标偏移时才有效。 That's half the battle, and probably why Microsoft still marks datetimeoffset as not "daylight savings aware" in the docs . 这只是成功的一半,也可能是为什么微软仍然将datetimeoffset标记为文档中没有“夏令时意识”。

我知道问题是如何在SQLCLR上下文中使用TimeZoneInfo,但我认为我只是添加了虽然不支持TimeZoneInfo(正如@MattJohnson优雅地写的那样),TimeZone仍然可以使用而不需要使程序集不安全。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将凭据映射到 SQL Server 中的 SQLCLR 程序集? - How do I map a credential to a SQLCLR assembly in SQL Server? 问题在MS SQL Server 2012中将Oracle.DataAccess注册为SQLCLR程序集 - Problems Registering Oracle.DataAccess as SQLCLR assembly in MS SQL Server 2012 如何将参数传递给外部(SQLCLR)SQL Server触发器 - How to pass arguments to an external (SQLCLR) SQL Server trigger 如何将SQLCLR更新推送到(CI)服务器 - How to push SQLCLR updates to your (CI) server .Net TimeZoneInfo.GetUtcOffset 如何工作? - How does .Net TimeZoneInfo.GetUtcOffset work? 我想使用 LAG 函数在另一列中运行总计,但它在 SQL Server 2012 中不起作用 - I want use LAG function for running total in another column, but it does not work in SQL Server 2012 SQLCLR 程序集注册失败(类型加载失败) - SQLCLR assembly registration failed (Type load failed) 如何将夏时制使用TimeZoneInfo类转换为UTC - How to use TimeZoneInfo Class with daylight savings To CONVERT TO UTC 如何从LINQ to SQL中的SQL Server 2012识别FormatException的来源 - How to identify source of a FormatException from SQL Server 2012 in LINQ to SQL 将我的第一个SQLCLR存储过程部署到Amazon RDS SQL Server实例 - Deploying my first SQLCLR stored procedure to Amazon RDS SQL Server instance
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM