sql >> Database >  >> RDS >> Sqlserver

Hoe gebruik je TimeZoneInfo in een SQLCLR-assembly in SQL Server 2012?

Bijgewerkt antwoord

Ik heb het hulpprogramma geschreven waar ik het over had in het oorspronkelijke antwoord, dat je hier kunt vinden .

Vanaf SQL Server 2016 (en Azure SQL Database), kunt u nu ook de AT TIME ZONE gebruiken trefwoord om tussen tijdzones te converteren.

Oorspronkelijk antwoord

Helaas is er geen goede oplossing voor het werken met tijdzones in SQL Server.

Ik heb het probleem dat je hebt gelinkt grondig onderzocht, samen met deze ook. Er zijn geen ingebouwde tijdzonefuncties en elk gebruik van TimeZoneInfo in SQLCLR vereist dat de assembly als "onveilig" wordt geregistreerd. Dit is meestal niet gewenst.

Ik heb ook onderzoek gedaan met behulp van Noda Time van SQLCLR. Je kunt erover lezen in dit nummer . Het moest ook als "onveilig" worden geregistreerd vanwege de manier waarop bepaalde items intern in de cache worden opgeslagen.

Uiteindelijk is het probleem met beide items dat er geen manier is om iets in SQLCLR te cachen. U kunt statische variabelen niet op een threadveilige manier gebruiken, en u kunt geen threadsynchronisatie uitvoeren of klassen zoals ConcurrentDictionary gebruiken . SQL wil volledige controle hebben over het threading-model van de assembly. Alleen single-threaded use-once-and-throw-away stijlcode werkt in "veilige" assemblages. Ik heb me hier diep in verdiept in deze vraag:Multithreaded caching in SQL CLR

Hopelijk komt er uiteindelijk een build van Noda Time zijn die zal werken in SQLCLR, maar het zal een speciale build zijn die geen caching uitvoert. Het zal dus niet zo snel presteren, maar het zal de klus klaren terwijl het nog steeds veilig is.

TimeZoneInfo zal waarschijnlijk niet veranderen. Dus tenzij het SQL Server-team ooit tijdzonefuncties correct rechtstreeks in SQL Server brengt (zoals Oracle en Postgres doen), dan heb je maar een paar opties:

  • Probeer geen tijdzoneconversies in de gegevenslaag. Werken met datetime of datetime2 waarden in UTC, of ​​gebruik datetimeoffset waarden met enige offset. Maar doe alle conversies tussen tijdzones in de applicatielaag. Dit is voorlopig mijn beste aanbeveling.

  • Kopieer alle gegevens voor de tijdzones naar daadwerkelijke SQL-tabellen en schrijf functies die met die gegevens werken. Dit is niet het beste idee, omdat de gegevens vaak veranderen, dus tabelonderhoud kan een uitdaging zijn. Het kan ook een uitdaging zijn om de functies nauwkeurig te krijgen, inclusief alle regels voor veranderingen in de zomertijd. Ik ken geen project waarin dit mooi en netjes is gebundeld, maar als iemand dat wel is, laat het me dan weten in reacties.

  • Schakel xp_regread in en werk met de tijdzonegegevens rechtstreeks vanuit de Windows-registersleutels. Updates zouden voor u worden gedaan, maar u heeft nog steeds dezelfde uitdagingen bij het schrijven van deze functies. En het inschakelen van registerlezen is misschien net zo'n veiligheidsrisico als het inschakelen van onveilige CLR-assembly's.

Een ander idee dat ik overweeg is het schrijven van een IANA/Olson TZDB parser en functies specifiek voor SQL Server. Dit zou vergelijkbaar zijn met optie 2 hierboven, maar op een onderhoudbare manier en met IANA-standaardgegevens in plaats van Windows-tijdzones. Misschien kom ik hier ooit achter, of misschien is iemand me voor. Nogmaals, ik ben niet op de hoogte van een huidig ​​project dat dit doet, maar als iemand er een weet, laat het me dan weten in opmerkingen. (klaar - zie update bovenaan )

Over SWITCHOFFSET - dat werkt alleen als u de doeloffset al weet. Dat is het halve werk, en waarschijnlijk de reden waarom Microsoft nog steeds datetimeoffset markeert als niet "op de hoogte van de zomertijd" in de documenten .



  1. SCD-type 6

  2. Fix Toegang geweigerd voor gebruiker 'root'@'localhost' voor phpMyAdmin

  3. Een INSERT Pass-Through-query uitvoeren in SQL Server

  4. Ubuntu 18.04 voor SQL Server 2019 op virtuele machine installeren met VMware Workstation