Status: New
Owner: ----
New issue 217 by mj1856: Compile flag without BCL support (for SQLCLR)
http://code.google.com/p/noda-time/issues/detail?id=217
Since SQL Server doesn't have any built-in support for time zone
conversions (while Oracle and MySql have tzdb support built in), I thought
I would try to use NodaTime from a SQLCLR user defined function. This came
up while I was looking into this question
http://stackoverflow.com/q/16231482/634824
Apparently, it's really difficult to use the BCL TimeZoneInfo class from
SQLCLR because it's marked with a HostProtection attribute with
MayLeakOnAbort=true. (yikes)
So of course, I thought NodaTime would be a great alternative. Well, at
first, SQL wouldn't even load the NodaTime assembly into its catalog.
There's a few restrictions that static fields must be marked readonly. We
had a few that weren't. Also, it didn't like caching the
TimeZoneInfo.Local value in a static field, so I had to bypass that. After
working through the exceptions it complained about during loading, I was
ultimately able to get the assembly to load and show up in the database's
assembly catalog.
Then I wrote a simple SQL CLR function:
[SqlFunction]
public static SqlDateTime UtcToZone(SqlDateTime dateTime, SqlString zoneId)
{
var zone = DateTimeZoneProviders.Tzdb[zoneId.Value];
var dtUtc = DateTime.SpecifyKind(dateTime.Value, DateTimeKind.Utc);
var instant = Instant.FromDateTimeUtc(dtUtc);
var dtConverted = instant.InZone(zone).ToDateTimeUnspecified();
return new SqlDateTime(dtConverted);
}
Of course, it needs some argument checking, but it should work as a simple
test. This loaded into SQL just fine. Then I tried to run it, as such:
select dbo.UtcToZone(GETUTCDATE(), 'America/Phoenix')
And I fail again. It seems just loading the NodaTime assembly initializes
the Bcl DateTimeZone provider, and calls into TimeZoneInfo, which gives the
same problems as before:
Msg 6522, Level 16, State 2, Line 7
A .NET Framework error occurred during execution of user-defined routine or
aggregate "UtcToZone":
System.TypeInitializationException: The type initializer
for 'NodaTime.DateTimeZoneProviders' threw an exception. --->
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
System.Security.HostProtectionException:
at NodaTime.TimeZones.BclDateTimeZoneSource.GetIds()
at NodaTime.TimeZones.DateTimeZoneCache..ctor(IDateTimeZoneSource source)
at NodaTime.DateTimeZoneProviders..cctor()
System.TypeInitializationException:
at NodaTime.DateTimeZoneProviders.get_Tzdb()
at NodaSQL.UserDefinedFunctions.UtcToZone(SqlDateTime dateTime,
SqlString zoneId)
.
So, it looks like getting full NodaTime implementation is going to have the
same problems because it references TimeZoneInfo. Is there any way we
could have some conditional compilation to compile NodaTime with only TZDB
support?
Do you think even without this that we'd run into other SQL CLR
restrictions?
--
You received this message because this project is configured to send all
issue notifications to this address.
You may adjust your notification preferences at:
https://code.google.com/hosting/settings