日付がNumeric(8)値としてYYYYMMDD形式で格納されているレガシーデータベースから一部のデータを抽出しました。それらを同じ形式のステージングテーブルに保存しましたが、SQL Serverで実際の日付フィールドに変換したいので、整数から日付への変換オプションを探して、さまざまな方法を考えましたCAST
またはCONVERT
に関連するもの。
ただし、Squirrel-SQL(v3.9.1、Java 1.8.221)を使用してdate
データ型で変換オプションを使用してクエリをテストしているとき(これは、時間の値はありません)、返される日付は2日ずれています。
_select cast('20200101' as date) ,
cast(left(20200101, 8) as date) ,
convert(date, cast(20200101 as char(10)), 112) ,
convert(date, convert(char(8), 20200101)) ,
convert(datetime, convert(char(8), 20200101)) ,
dateadd(day, datediff(day,0,cast(20200101 as varchar(10))), 0) ,
convert(date,dateadd(day, datediff(day,0,cast(20200101 as varchar(10))), 0))
/* results:
2019-12-30
2019-12-30
2019-12-30
2019-12-30
2020-01-01 00:00:00.0
2020-01-01 00:00:00.0
2019-12-30
*/
_
特に、最後の2つでは、DateAdd
式が明示的に正しい日時を生成し、その上でConvert
を使用すると、2日間バックアップされることに注意してください。
SSMSで同じクエリを実行すると、期待値が生成されます。
この動作を説明するために提供するものはどこにも見つからなかったので、あなたの一人がいくつかの光を当てることができることを望んでいますか?
関連する可能性のあるもう1つの手がかり(ただし、使用可能なgoogleの結果も生成されていない)は、SysDateTimeOffset()
は影響を受けませんが、SysUTCDateTime()
も2日間ずれているようです:
_select cast(sysdatetimeoffset() as varchar(40)) as Sysdtoff, sysutcdatetime() as sysUTC
/* output (actual date should be 1/22)
2020-01-22 11:45:39.9878059 -06:00
2020-01-20 17:45:39.9878059
*/
_
サーバーの実際の時刻は正しく、予想されるタイムゾーン(-6時間)に設定されています。Squirrel-SQLの設定を調べても、日付関連のオプションは表示されません。
整数から日付への変換では、msdbでdbo.agent_datetime(date int、time int)というシステム関数を使用することを検討できます。これは自動的に日時に変換されます(日付としてキャストできます)。
ソース: https://blog.sqlauthority.com/2015/03/13/sql-server-interesting-function-agent_datetime/