sql >> Base de Datos >  >> RDS >> Sqlserver

¿Cómo se usa TimeZoneInfo en un ensamblado SQLCLR en SQL Server 2012?

Respuesta actualizada

He escrito la utilidad de la que hablé en la respuesta original, que puedes encontrar aquí .

Además, a partir de SQL Server 2016 (y Azure SQL Database), ahora puede usar AT TIME ZONE palabra clave para convertir entre zonas horarias.

Respuesta original

Desafortunadamente, no existe una gran solución para trabajar con zonas horarias en SQL Server.

Investigué a fondo el problema que vinculaste, junto con este además. No hay funciones de zona horaria integradas y cualquier uso de TimeZoneInfo en SQLCLR requiere que el ensamblado se registre como "inseguro". Esto generalmente no se desea.

También investigué usando Noda Time de SQLCLR. Puede leer sobre esto en este problema . También tuvo que registrarse como "inseguro" debido a la forma en que ciertos elementos se almacenan en caché internamente.

En última instancia, con cualquiera de los elementos, el problema es que no hay forma de almacenar en caché nada en SQLCLR. No puede usar variables estáticas de manera segura para subprocesos, y no puede sincronizar subprocesos ni usar clases como ConcurrentDictionary . SQL quiere tener el control total del modelo de subprocesos del ensamblaje. Solo el código de estilo de uso único y de un solo subproceso funciona en ensamblajes "seguros". Profundicé en esto en esta pregunta:Caché multiproceso en SQL CLR

Con suerte, habrá eventualmente ser una compilación de Noda Time que funcionará en SQLCLR, pero será una compilación especial que no realiza ningún almacenamiento en caché. Por lo tanto, no funcionará tan rápido, pero hará el trabajo sin dejar de ser seguro.

TimeZoneInfo no es probable que cambie. Entonces, a menos que el equipo de SQL Server traiga las funciones de zona horaria directamente a SQL Server correctamente (como lo hacen Oracle y Postgres), entonces solo tiene algunas opciones:

  • No intente realizar conversiones de zona horaria en la capa de datos. Trabajar con datetime o datetime2 valores en UTC, o use datetimeoffset valores con cualquier compensación. Pero haga todas las conversiones entre zonas horarias en la capa de aplicación. Esta es mi mejor recomendación por ahora.

  • Copie todos los datos de las zonas horarias en tablas SQL reales y escriba funciones que funcionen con esos datos. Esta no es la mejor idea, porque los datos cambian con frecuencia, por lo que el mantenimiento de la tabla puede ser un desafío. También puede ser un desafío lograr que las funciones sean precisas, incluidas todas las reglas de los cambios de horario de verano. No tengo conocimiento de ningún proyecto que tenga este paquete ordenado y ordenado, pero si alguien lo está, házmelo saber en los comentarios.

  • Habilitar xp_regread y trabaje con los datos de la zona horaria directamente desde las claves de registro de Windows. Las actualizaciones se realizarán por usted, pero aún tiene los mismos desafíos al escribir estas funciones. Y habilitar las lecturas del registro podría ser un riesgo de seguridad tan grande como habilitar ensamblados CLR inseguros de todos modos.

Otra idea que estoy considerando es escribir un IANA/Olson TZDB analizador y funciones específicamente para SQL Server. Esto sería similar a la opción 2 anterior, pero se haría de forma mantenible y con los datos estándar de la IANA en lugar de las zonas horarias de Windows. Tal vez llegue a esto algún día, o tal vez alguien se me adelante. Nuevamente, no tengo conocimiento de ningún proyecto actual que haga esto, pero si alguien sabe de uno, hágamelo saber en los comentarios. (hecho - ver actualización en la parte superior )

Con respecto a SWITCHOFFSET - eso solo funciona cuando ya conoce el desplazamiento objetivo. Esa es la mitad de la batalla, y probablemente la razón por la que Microsoft todavía marca datetimeoffset como no "consciente del horario de verano" en los documentos .