日時列を持ついくつかの行を持つ古いテーブルがあります。これをdatetimeoffsetに切り替えたいのですが、既存のデータを転送できるようにしたいのです。だから私は次のようなことをしています:
SET IDENTITY_INSERT Table_Temp ON
INSERT INTO Table_Temp
(Col0, ... ColN,)
SELECT
COl0,.... ColN, from
Table_Original;
SET IDENTITY_INSERT Table_Temp OFF
これは機能しますが、dattimeからdatetimeoffsetへの割り当てを行うとオフセットセットは0になります。幸い、設定したいオフセットは現在のシステムのオフセットです。私はtsqlの第一人者ではありませんが、これを行う簡単な方法を理解できないようです。
変換内でオフセットを設定できるようにしたい。私はc#ユーティリティ(またはPowerShell)を使用することにしましたが、単純にしておきたいと思います。
Datetimeoffsetタイプを認識しているバージョンのSQLServerを使用している場合、次の構文は、サーバーのローカルtzオフセットを取得するために機能します。
select datepart(tz,sysdatetimeoffset())
結果は分単位です。
以下のドキュメントを参照してください。おそらく次のようなものが必要です。
-- up here set the @time_zone variable.
INSERT INTO Table_Temp
(Col0, ... ColN,)
SELECT
COl0, TODATETIMEOFFSET(COLDATE, @time_zone),.... ColN, from
Table_Original;
SWITCHOFFSET関数は、UTC値を保持しながら、入力DATETIMEOFFSET値を指定されたタイムゾーンに調整します。構文はSWITCHOFFSET(datetimeoffset_value、time_zone)です。たとえば、次のコードは、現在のシステムのdatetimeoffset値をタイムゾーンGMT + 05:00に調整します。
SELECT SWITCHOFFSET(SYSDATETIMEOFFSET()、 '-05:00');
したがって、現在のシステムのdatetimeoffset値が2009年2月12日10:00:00.0000000 -08:00の場合、このコードは値2009年2月12日13:00:00.0000000-05:00を返します。
TODATETIMEOFFSET関数は、入力された日付と時刻の値のタイムゾーンオフセットを設定します。その構文はTODATETIMEOFFSET(date_and_time_value、time_zone)です。
この関数は、いくつかの点でSWITCHOFFSETとは異なります。まず、入力としてのdatetimeoffset値に制限されません。むしろ、任意の日付と時刻のデータ型を受け入れます。次に、ソース値と指定されたタイムゾーンのタイムゾーンの差に基づいて時刻を調整しようとはせず、代わりに、指定されたタイムゾーンをdatetimeoffset値として入力した日付と時刻の値を返します。
TODATETIMEOFFSET関数の主な目的は、タイムゾーンを認識しないタイプを、指定されたタイムゾーンオフセットによってDATETIMEOFFSETに変換することです。指定された日付と時刻の値がDATETIMEOFFSETの場合、TODATETIMEOFFSET関数は、同じ元のローカルの日付と時刻の値に新しい指定されたタイムゾーンオフセットを加えたものに基づいてDATETIMEOFFSET値を変更します。
たとえば、現在のシステムのdatetimeoffset値は2009年2月12日10:00:00.0000000 -08:00であり、次のコードを実行します。
SELECT TODATETIMEOFFSET(SYSDATETIMEOFFSET()、 '-05:00');
値2009年2月12日10:00:00.0000000-05:00が返されます。 SWITCHOFFSET関数は、入力(-08:00)と指定されたタイムゾーン(-05:00)のタイムゾーンの違いに基づいて時間を調整したため、2009年2月12日13:00:00.0000000-05:00を返したことを思い出してください。 。
前述のように、TODATETIMEOFFSET関数は、任意の日付と時刻のデータ型を入力として使用できます。たとえば、次のコードは、現在のシステムの日付と時刻の値を取得し、タイムゾーンが-00:05のdatetimeoffset値として返します。
SELECT TODATETIMEOFFSET(SYSDATETIME()、 '-05:00');
タイムゾーンオフセットが同じ年内に変更されるため、DST保存がターゲットタイムゾーンでアクティブになっている場合、これらの変換機能は正しく機能しません。
以下を使用して、現在のSQLサーバーのオフセットが何であるかを把握できます。
select datediff(MI,getdate(), getutcdate())
30分、さらには15分タイムゾーンもあるため、オフセットは数時間ではなく数分で取得する必要があります。
議事録の値を使用すると、次のようなものを使用して、入力する値を変更できます(履歴的にすべて現地時間として記録されていると仮定)。
select dateadd(mi,datediff(MI,getdate(), getutcdate()), yourDateField)
効率のために、私はそれを一度変数に計算し、それを使用します。違いは変わらないからです。
これは、すでに提供されている回答のわずかなバリエーションであり、DSTの変更は考慮されていません。ただし、多くの目的には十分な場合があります。
dateadd(minute, -datepart(tz, sysdatetimeoffset()), @legacyDatetime)
この問題を正しく解決しようとしている人にとって、ここでDSTを考慮することは、それを行うためのツールです。