How to migrate DateTime values to DateTimeOffset in SQL Server?
给定一个带有DateTime列的SQL表和过去3年中大约10万行不同日期(本地时间PST值),将这些列值迁移到DateTimeOffset以"添加"缺少的utc tz偏移信息的最佳策略是什么?
已存储的现有DateTime值没有任何时区/ utc偏移详细信息。存储的日期始终代表太平洋时间(-800或-700,具体取决于夏令时)。目标是追溯将tz偏移量添加到所有现有数据,并假设日期来自太平洋时间(无论正确的偏移量是在日期指定的时刻)
-
在SQL中,这种类型的迁移的最佳实践是什么,而不会丢失任何数据或更改现有值?
-
进入下一步,迁移整个中等大小的数据库(在100个表中约100gb,每个表有2个DateTime列)的最有效方法是什么才能使用DateTimeOffset列和值?
-
在PST / PDT转换日期的凌晨2点/期间记录的日期时间会发生什么变化?是否会发生数据丢失?
SQL Server 2008 + C#4.5
如果这不是正确的方向,请指出我正确的方向,谢谢!
编辑:耶,赏金时间。
SQL Server 2016引入了T-SQL语法
因此,如果您知道数据的时区,则可以使用简单的alter and update脚本附加偏移量,如下所示(假设您有一个名为MyTable的表具有名为DateTimeColumn的datetime2列):
1 2 3 4 5 | ALTER TABLE MyTable ALTER COLUMN DateTimeColumn datetimeoffset; UPDATE Mytable SET DateTimeColumn = CONVERT(datetime2, DateTimeColumn) AT TIME ZONE 'Pacific Standard Time' |
考虑夏令时(DST),不应有数据丢失。
(我知道OP指定了SQL Server 2008,很久以前就问过并回答了这个问题,但希望这个答案可以帮助那些目前正在努力解决同类问题的人。)
夏令时并不总是一门精确的科学。例如。 2007年北美使用的时期发生了规则变化。因此,建议使用相关日期填充表格。例如。 2000-2013:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | -- Populate a table with PST daylight saving start/end times -- Example data for 2000-2013 - sourced from -- http://www.timeanddate.com/worldclock/timezone.html?n=137 CREATE TABLE dst (START DateTime, [END] DateTime); INSERT INTO dst (START, [END]) VALUES ('02:00 2 Apr 2000', '02:00 29 Oct 2000'); INSERT INTO dst (START, [END]) VALUES ('02:00 1 Apr 2001', '02:00 28 Oct 2001'); INSERT INTO dst (START, [END]) VALUES ('02:00 7 Apr 2002', '02:00 27 Oct 2002'); INSERT INTO dst (START, [END]) VALUES ('02:00 6 Apr 2003', '02:00 26 Oct 2003'); INSERT INTO dst (START, [END]) VALUES ('02:00 4 Apr 2004', '02:00 31 Oct 2004'); INSERT INTO dst (START, [END]) VALUES ('02:00 3 Apr 2005', '02:00 30 Oct 2005'); INSERT INTO dst (START, [END]) VALUES ('02:00 2 Apr 2006', '02:00 29 Oct 2006'); INSERT INTO dst (START, [END]) VALUES ('02:00 11 Apr 2007', '02:00 4 Oct 2007'); INSERT INTO dst (START, [END]) VALUES ('02:00 9 Apr 2008', '02:00 2 Nov 2008'); INSERT INTO dst (START, [END]) VALUES ('02:00 8 Apr 2009', '02:00 1 Nov 2009'); INSERT INTO dst (START, [END]) VALUES ('02:00 14 Apr 2010', '02:00 7 Nov 2010'); INSERT INTO dst (START, [END]) VALUES ('02:00 13 Apr 2011', '02:00 6 Nov 2011'); INSERT INTO dst (START, [END]) VALUES ('02:00 11 Apr 2012', '02:00 4 Nov 2012'); INSERT INTO dst (START, [END]) VALUES ('02:00 10 Apr 2013', '02:00 3 Nov 2013'); |
当然,你可能需要更多的东西 - 将这样做作为读者的练习:-)
好的,所以假设您使用整个可能的范围填充上表,并且您在表
1 2 3 4 5 6 7 8 9 10 11 | -- Convert sample dates to PST offset with daylight saving where appropriate SELECT test.dt, CAST(CONVERT(VARCHAR(23), test.dt, 126) + -- Convert to ISO8601 format CASE WHEN dst.start IS NULL THEN '-08:00' -- No record joined so not within DST period ELSE '-07:00' -- DST record joined so is within DST period END AS DateTimeOffset) AS dto FROM test LEFT JOIN dst -- Join on daylight savings table to find out whether DST applies ON test.dt >= dst.start AND test.dt <= dst.[END] |
这是一个SQL小提琴演示。