Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Wie verwendet man TimeZoneInfo in einer SQLCLR-Assembly in SQL Server 2012

Aktualisierte Antwort

Ich habe das Dienstprogramm geschrieben, über das ich in der ursprünglichen Antwort gesprochen habe, das Sie hier finden können .

Außerdem können Sie ab SQL Server 2016 (und Azure SQL-Datenbank) jetzt die AT TIME ZONE verwenden Schlüsselwort zum Umwandeln zwischen Zeitzonen.

Originalantwort

Leider gibt es keine großartige Lösung für die Arbeit mit Zeitzonen in SQL Server.

Ich habe das von Ihnen verlinkte Problem zusammen mit diesem intensiv untersucht Auch. Es gibt keine eingebauten Zeitzonenfunktionen und keine Verwendung von TimeZoneInfo in SQLCLR erfordert, dass die Assembly als „unsicher“ registriert wird. Dies ist normalerweise nicht erwünscht.

Ich habe auch mit Noda Time nachgeforscht von SQLCLR. Sie können darüber in dieser Ausgabe nachlesen . Außerdem musste es aufgrund der Art und Weise, wie bestimmte Elemente intern zwischengespeichert werden, als "unsicher" registriert werden.

Letztendlich besteht das Problem bei beiden Elementen darin, dass es keine Möglichkeit gibt, etwas in SQLCLR zwischenzuspeichern. Sie können statische Variablen nicht Thread-sicher verwenden, und Sie können keine Thread-Synchronisierung durchführen oder Klassen wie ConcurrentDictionary verwenden . SQL möchte die vollständige Kontrolle über das Threading-Modell der Assembly haben. In „sicheren“ Assemblys funktioniert nur Singlethread-Code im „Use-once-and-throw-away“-Stil. Ich habe mich in dieser Frage eingehend damit befasst:Multithread-Caching in SQL CLR

Hoffentlich gibt es das irgendwann ein Build von Noda Time sein, der in SQLCLR funktioniert, aber es wird ein spezieller Build sein, der kein Caching durchführt. Es wird also nicht so schnell arbeiten, aber es erledigt die Arbeit und ist dennoch sicher.

TimeZoneInfo wird sich wahrscheinlich nicht ändern. Wenn also das SQL Server-Team Zeitzonenfunktionen nicht jemals richtig in SQL Server einführt (wie es Oracle und Postgres tun), haben Sie nur wenige Optionen:

  • Versuchen Sie nicht, Zeitzonenkonvertierungen in der Datenschicht durchzuführen. Arbeiten Sie mit datetime oder datetime2 Werte in UTC oder verwenden Sie datetimeoffset Werte mit beliebigem Offset. Führen Sie jedoch alle Konvertierungen zwischen Zeitzonen in der Anwendungsschicht durch. Das ist vorerst meine beste Empfehlung.

  • Kopieren Sie alle Daten für die Zeitzonen in tatsächliche SQL-Tabellen und schreiben Sie Funktionen, die mit diesen Daten arbeiten. Dies ist nicht die beste Idee, da sich die Daten häufig ändern, sodass die Tabellenpflege eine Herausforderung sein kann. Es kann auch eine Herausforderung sein, die Funktionen genau zu erhalten, einschließlich aller Regeln für die Umstellung auf Sommerzeit. Mir ist kein Projekt bekannt, das dies schön und ordentlich gebündelt hat, aber wenn jemand es tut - dann lass es mich bitte in den Kommentaren wissen.

  • Aktivieren Sie xp_regread und arbeiten Sie mit den Zeitzonendaten direkt aus den Windows-Registrierungsschlüsseln. Updates würden für Sie durchgeführt, aber Sie haben immer noch die gleichen Herausforderungen beim Schreiben dieser Funktionen. Und das Aktivieren von Registry-Lesevorgängen könnte sowieso ein ebenso großes Sicherheitsrisiko darstellen wie das Aktivieren unsicherer CLR-Assemblys.

Eine andere Idee, die ich in Betracht ziehe, ist, eine IANA/Olson TZDB zu schreiben Parser und Funktionen speziell für SQL Server. Dies wäre ähnlich wie Option 2 oben, aber auf wartbare Weise und mit IANA-Standarddaten anstelle von Windows-Zeitzonen. Vielleicht komme ich eines Tages dazu, oder vielleicht kommt mir jemand zuvor. Auch hier ist mir kein aktuelles Projekt bekannt, das dies tut, aber wenn jemand eines kennt, lass es mich bitte in den Kommentaren wissen. (erledigt - siehe Update oben )

Bezüglich SWITCHOFFSET - das funktioniert nur, wenn man den Zieloffset bereits kennt. Das ist die halbe Miete und wahrscheinlich der Grund, warum Microsoft immer noch datetimeoffset markiert in den Dokumenten als nicht "sommerzeitbewusst" bezeichnet .