8

.NET TimeZoneInfo クラスは優れており、SQL 2005 データベースに複数のタイム ゾーンからデータを記録する際の問題をすべて解決してくれると思いました。

データベースの UTC 日時を他のタイム ゾーンに変換するには、TimeZoneInfo.FindSystemTimeZoneById() を使用してタイム ゾーンを TimeZoneInfo クラスに取得し、TimeZoneInfo.ConvertTimeFromUtc() を呼び出します。素晴らしい!これを SQL .NET CLR から呼び出すだけです。

しかし...TimeZoneInfo には MayLeakOnAbort のホスト保護属性があります。

VS 2008 を使用して SQL 関数またはストアド プロシージャを作成すると、system.TimeZoneInfo クラスが使用されていることがわかりません。また、何らかの方法で TimeZoneInfo クラスを参照できたとしても、アセンブリを SQL Sever 2005 に登録しようとすると、何らかのセキュリティ例外が発生する可能性があると想定しています。

ヘルプ!SQL Server 2005 から TimeZoneInfo クラスとそのすべての機能にアクセスする方法はありますか?

注意: 最初の回答の後にこの警告を追加しました:

世界中のさまざまな場所にサイトがあります。サイト レベルでの傾向分析が必要になる可能性があるイベントに対して、ローカル時間と UTC 時間をデータベースに保存する必要があります。トレンドは 1 年間で 52,000 を超えるデータ ポイントで構成される場合があるため、効率を高めるために、時間を UTC で DB に保存し、クライアント上のすべてのデータ ポイントを変換することはできません。したがって、DB 内で任意のタイムゾーンの現地時間を UTC 時間との間で変換する機能が必要です。

4

7 に答える 7

3

私はSQL 2008データベースでこれをやり終えました。

まず、DB を信頼できるものに設定し、所有者が正しいことを確認する必要がありました。

use [myDB]
go
alter database [myDB] set trustworthy on
go

exec sp_changedbowner 'sa'
go

次に、.NET ソリューションを作成しました

Imports System
Imports System.Data
Imports System.Data.SqlClient
Imports System.Data.SqlTypes
Imports Microsoft.SqlServer.Server
Imports System.Collections.ObjectModel
Imports System.Runtime.InteropServices

Partial Public Class StoredProcedures
    <Microsoft.SqlServer.Server.SqlProcedure()> _
    Public Shared Sub sp_ConvertTime(ByVal UTCTime As DateTime, ByVal ZoneID As String, <Out()> ByRef Output As DateTime)
    Dim sp As SqlPipe = SqlContext.Pipe

    Dim ConvertedTime As DateTime
    Dim tzUTC = TimeZoneInfo.FindSystemTimeZoneById("UTC")
    Dim tzNew = TimeZoneInfo.FindSystemTimeZoneById(ZoneID)

    ConvertedTime = TimeZoneInfo.ConvertTime(UTCTime, tzUTC, tzNew)

    Output = ConvertedTime
    sp.Send(ConvertedTime)

    ConvertedTime = Nothing
    tzUTC = Nothing
    tzNew = Nothing
    sp = Nothing

End Sub
End Class

展開する前に、アクセス許可レベルをUnsafeに設定しました。

次に、ビルド エラーの [出力] ウィンドウを確認し、それらを修正しました。

これがSQLテストです

DECLARE @UTCTime datetime
DECLARE @ZoneID varchar(21)
DECLARE @NewTime datetime

SET @UTCTime = GETUTCDATE()
SET @ZoneID = 'Central Standard Time'

exec sp_ConvertTime @UTCTime, @ZoneID, @NewTime OUTPUT
select @NewTime AS NewTime
于 2012-09-25T16:02:00.763 に答える
1

SQLからTimeZoneInfoクラスにアクセスできるかどうかはわかりませんが、データベースでUTCを使用し、クライアントが現地時間に変換することをお勧めします。

したがって、データベースに書き込むたびに、現地時間からUTCに変換し、データベースから読み取るたびに、UTCから現地時間に変換します。

編集:私が問題について理解していることから、私がまだお勧めする解決策は次のとおりです:

1)データベースにUTCで日付を保存します。2)クライアントの現地時間を計算します。

2はいくつかの方法で行うことができます。推奨される方法は、DataColumnクラス(*)でDateTimeModeをLocal(またはUTC)に設定することです。現地時間でレポートが必要な場合はローカルを使用し、UTCでレポートが必要な場合はUTCを使用します。

(*)Visual Studioのデザイナーに問題があることに注意してください。ブログ投稿を参照してください:http://bethmassi.blogspot.com/2006/01/serializing-data-across-time-zones-in.html、バグレポート:http ://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID = 96118

于 2009-03-05T12:58:51.950 に答える
1

解決策は次のとおりです。

  1. TimeZoneInfo クラスの機能をラップする CLR ストアド プロシージャまたは UDF を作成します。このガイドに従ってください: http://www.codeproject.com/KB/cs/CLR_Stored_Procedure.aspx
  2. TimeZoneInfo には .NET 3.5 が必要です。ただし、System.Core v3.5 は Sql Server 2005 での検証に合格しません。そのため、System.Core に対して CREATE ASSEMBLY を実行する必要があります。詳細を参照してください: http://weblogs.asp.net/paulomorgado/archive/2009/06/13/playing-with-sql-server-clr-integration-part-iv-deploying-to-sql-server-2005.aspx

System.Core を UNSAFE として登録する必要があることに注意してください... DBA に問題が発生する可能性があります。

さらに、Sql Server 2008 (.NET 3.5 を含む) にデプロイする場合でも、TimeZoneInfo の安全でないメソッドを使用するため、カスタム アセンブリは UNSAFE である必要があります: http://social.msdn.microsoft.com/Forums/en /sqlnetfx/thread/d0515862-eb87-4a13-bab4-0e343983823a

これを試してみたところ、MayLeakOnAbort に関するメッセージが表示されました。

あなたの環境でUNSAFEがOKなら、できるはずです。

于 2010-03-18T21:53:33.740 に答える
1

レポート サービスで使用されていたクエリで、ローカルと UTC の間で変換したかったため、この同じ問題に遭遇しました。私はあなたがこれで経験しているのとまったく同じように見えるものを経験しました。私の解決策...

私は、TimeZoneInfo オブジェクトを通過し、データベースの TimeZoneInfo テーブルにエントリを書き込むスタンドアロン アプリの作成を開始しました。開始年から終了年までの毎年のすべてのオフセット (夏時間オフセットを含む) を保存しました (これらはスタンドアロン アプリへの引数でした)。

このテーブルから、UTC またはローカルの日付とタイムゾーンを取得し、TimeZoneInfo ルックアップ テーブルを使用して適切な年とタイムゾーンの適切なオフセットを取得し、変換された日時を返す SQL 関数を作成することができました。 UTC またはローカルに。

残念ながら、私はまだ終わっていません。(TimeZoneInfo オブジェクトとは異なり) SQL Server に対して安全なライブラリを使用して、システムの現在のタイムゾーンを返す CLR 関数を作成する必要がありました。現時点ではコードにアクセスできませんが、TimeZone オブジェクトを使用したと思います。

http://msdn.microsoft.com/en-us/library/system.timezone_members.aspx

要約すると、システムのタイム ゾーンを返す CLR 関数、つまり、さまざまな年の DLS 固有の情報を含むタイム ゾーン ルックアップ テーブルを生成するアプリがありました。タイムゾーンと日付を変換するストアド プロシージャですべてを締めくくりましたが、それ以来、美しく機能しています。

これは非常に単純に見えることを行うための巨大な回避策であることを理解していますが、安全な方法で仕事を完了しました.

于 2009-03-25T20:31:41.910 に答える
0

私たちはこれをしばらく探していましたが、良い方法を見つけることができませんでした。しばらく前に見たのを覚えていれば、それは SQL 2008 で追加されるもののリストにあったと思います。

于 2009-03-05T15:35:53.053 に答える
0

Channel9 でこの記事をチェックしましたか? CLR関数で探していることを実行しているようです...アクセスしたいすべてのグッズを取得できるとは思いませんが...しかし、それは始まりです。

http://channel9.msdn.com/playground/Sandbox/139123/

そのスレッドのポスターの1つが言及している問題は、p/invokeのために安全でないアセンブリであるということです。

于 2009-08-22T06:40:01.330 に答える
0

何年も同じ問題と戦った後、最終的にSQL Server Time Zone Supportのソリューションを構築することにしました。プロジェクトは、ここにリストされている標準の IANA タイム ゾーンを使用します。

例えば:

SELECT Tzdb.UtcToLocal('2015-07-01 00:00:00', 'America/Los_Angeles')

これは正確に尋ねられたものではないことは承知していますが、問題を同様にうまく解決すると思います。

于 2015-04-03T06:04:02.247 に答える