Die .NET TimeZoneInfo-Klasse ist großartig und ich dachte, sie würde alle meine Probleme mit der Aufzeichnung von Daten aus mehreren Zeitzonen in meiner SQL 2005-Datenbank beantworten.
Um eine UTC-Datetime in der Datenbank in eine andere Zeitzone zu konvertieren, würde ich die Zeitzone mit TimeZoneInfo.FindSystemTimeZoneById () in eine TimeZoneInfo-Klasse bringen und dann die TimeZoneInfo.ConvertTimeFromUtc () aufrufen. Brillant! Ich würde dies nur von der SQL .NET CLR aufrufen!
ABER ... TimeZoneInfo hat ein Host-Schutz-Attribut von MayLeakOnAbort.
Wenn ich VS 2008 verwende, um eine SQL-Funktion oder eine gespeicherte Prozedur zu erstellen, kann ich nicht einmal die system.TimeZoneInfo-Klasse sehen, die sie benutzt. Ich gehe auch davon aus, dass, selbst wenn ich irgendwie auf die TimeZoneInfo-Klasse verweisen könnte, ich wahrscheinlich eine Art Sicherheitsausnahme bekommen würde, wenn ich versuchen würde, die Assembly in SQL Server 2005 zu registrieren.
Hilfe! Gibt es eine Möglichkeit, auf die TimeZoneInfo-Klasse und alle ihre Ressourcen von SQL Server 2005 zuzugreifen?
NB: Ich habe diesen Vorbehalt erst nach der ersten Antwort hinzugefügt:
Wir haben Standorte an verschiedenen Standorten auf der ganzen Welt. Wir müssen die lokale Zeit und die UTC-Zeit in der Datenbank für Ereignisse speichern, die eine Trendanalyse auf Site-Ebene erfordern. Ein Trend kann aus über 52.000 Datenpunkten über ein Jahr bestehen. Aus Gründen der Effizienz kann ich also nicht einfach Zeiten in UTC in der Datenbank speichern und jeden Datenpunkt auf dem Client konvertieren. Daher brauche ich innerhalb der DB die Fähigkeit, eine lokale Zeit in jeder Zeitzone in die UTC-Zeit und umgekehrt umzuwandeln.
Ich habe gerade das in einer SQL 2008-Datenbank gemacht.
Zuerst musste ich die Datenbank vertrauenswürdig setzen und überprüfen, ob der Besitzer korrekt war.
%Vor%Als nächstes habe ich eine .NET-Lösung erstellt
%Vor%Vor der Bereitstellung habe ich die Berechtigungsebene auf Unsicher festgelegt.
Als nächstes habe ich es bereitgestellt. Ich habe das Ausgabefenster auf Buildfehler überprüft und diese korrigiert.
Hier ist der SQL-Test
%Vor%Ich weiß nicht, ob Sie von SQL aus auf die TimeZoneInfo-Klasse zugreifen können, aber es wird allgemein als gute Methode angesehen, bei UTC in der Datenbank zu bleiben, wobei der Client die Übersetzung in die lokale Zeit durchführt.
Sie übersetzen also jedes Mal, wenn Sie in die Datenbank schreiben, von der lokalen Zeit in die UTC, jedes Mal, wenn Sie aus der Datenbank lesen, übersetzen Sie von UTC in die lokale Zeit.
EDIT: Nach dem, was ich von dem Problem verstehe, ist die Lösung, die ich noch empfehlen würde:
1) Speichern Sie die Daten in UTC in der Datenbank. 2) Berechnen Sie die lokale Zeit im Client.
2 kann auf verschiedene Arten erfolgen. Die empfohlene Methode besteht darin, den DateTimeMode auf Local (oder Utc) in der DataColumn-Klasse (*) zu setzen. Wenn Sie einen Bericht in Ortszeit benötigen, verwenden Sie Lokal, wenn Sie ihn in UTC benötigen, verwenden Sie UTC.
(*) Bitte beachten Sie, dass es Probleme mit dem Designer in Visual Studio gibt, siehe Blogpost: Ссылка , Fehlerbericht: Ссылка
Ich stieß auf dasselbe Problem, weil ich in einer Abfrage, die von Reporting Services verwendet wurde, zwischen local und UTC konvertieren wollte. Ich ging durch genau dieselben Kämpfe, die du durchmachst. Meine Lösung ...
Ich habe angefangen, eine eigenständige App zu schreiben, die das TimeZoneInfo-Objekt durchlaufen hat und Einträge in eine TimeZoneInfo-Tabelle in meiner Datenbank geschrieben hat. Ich habe alle Offsets (einschließlich der Sommerzeit-Offsets) für jedes Jahr zwischen einem Startjahr und einem Endjahr gespeichert (dies waren Argumente für die Stand-alone-App).
Aus dieser Tabelle konnte ich dann einige SQL-Funktionen erstellen, die ein Datum in utc oder local und die Zeitzone verwenden, die TimeZoneInfo-Lookup-Tabelle verwenden, um den richtigen Offset für die richtige Zeit des Jahres und der Zeitzone zu erhalten Die Datetime wurde in UTC oder local konvertiert.
Leider war ich noch immer nicht fertig. Ich musste eine CLR-Funktion erstellen, die die aktuelle Zeitzone des Systems mithilfe einer Bibliothek zurückgab, die für SQL Server sicher war (anders als das TimeZoneInfo-Objekt). Ich habe momentan keinen Zugriff auf meinen Code, aber ich glaube, dass ich das TimeZone-Objekt verwendet habe.
Zusammenfassend hatte ich eine CLR-Funktion, die die Zeitzone des Systems zurückgab, eine App, die eine Zeitzonen-Nachschlagetabelle mit DLS-spezifischen Informationen für eine Reihe von Jahren erzeugte. Ich übertraf alles mit einer gespeicherten Prozedur, die eine Zeitzone und ein Datum für die Konvertierung einbezog und seither wunderbar funktioniert.
Ich verstehe, dass dies eine RIESIGE Arbeit ist, etwas zu tun, was ziemlich einfach zu sein scheint, aber es hat den Job auf eine sichere Art erledigt.
Hier ist eine Lösung:
Beachten Sie, dass Sie System.Core als UNSAFE ... registrieren müssen, damit DBA möglicherweise Probleme damit hat.
Selbst wenn Sie Sql Server 2008 bereitstellen (einschließlich .NET 3.5), müsste Ihre benutzerdefinierte Assembly UNSAFE sein, da sie unsichere Methoden von TimeZoneInfo verwendet: Zypern
Ich habe das versucht und eine Nachricht bezüglich MayLeakOnAbort erhalten.
Wenn UNSAFE in Ihrer Umgebung in Ordnung ist, sollten Sie es tun können.
Haben Sie diesen Artikel auf Channel9 gelesen? Scheint zu tun, was du in einer CLR-Funktion suchst ... obwohl ich nicht glaube, dass du ALLE Leckereien bekommst, auf die du zugreifen willst ... aber es ist ein Anfang.
Problem, das eines der Poster in diesem Thread erwähnt, ist jedoch, dass es wegen des p / Aufrufs eine unsichere Assembly ist.
Nachdem ich mich jahrelang mit demselben Problem herumgeschlagen habe, entschied ich mich schließlich, eine Lösung für Zeitzonenunterstützung für SQL Server zu entwickeln. Das Projekt verwendet die Standard-IANA-Zeitzonen , wie hier aufgelistet .
Zum Beispiel:
%Vor% Ich weiß, dass das nicht genau das ist, was gefragt wurde, aber ich denke, dass es das Problem genauso gut lösen wird.Tags und Links sql sql-server asp.net clr timezone