got*_*tqn 9 sql-server t-sql temporal-tables sql-server-2016
我有:
我正在使用以下语句使我的表成为临时表:
ALTER TABLE [dbo].[AnalysisCustomRollupsV2JoinGroups]
ADD [SysStartTime] DATETIME2(0) GENERATED ALWAYS AS ROW START HIDDEN CONSTRAINT DF_AnalysisCustomRollupsV2JoinGroups_SysStart DEFAULT GETUTCDATE()
,[SysEndTime] DATETIME2(0) GENERATED ALWAYS AS ROW END HIDDEN CONSTRAINT DF_AnalysisCustomRollupsV2JoinGroups_SysEnd DEFAULT CONVERT(DATETIME2(0), '9999-12-31 23:59:59'),
PERIOD FOR SYSTEM_TIME ([SysStartTime], [SysEndTime]);
ALTER TABLE [dbo].[AnalysisCustomRollupsV2JoinGroups]
SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.AnalysisCustomRollupsV2JoinGroupsChanges));
Run Code Online (Sandbox Code Playgroud)
问题:
在我的本地 SQL 实例上,我有很多数据库;查询在其中一些上成功运行非常奇怪,而在其中一些上它给了我以下错误:
消息 13542,级别 16,状态 0,第 51 行 ADD PERIOD FOR SYSTEM_TIME 在表 'dbo.AnalysisCustomRollupsV2JoinGroups' 上失败,因为有打开的记录,期间的开始时间设置为将来的某个值。
有时,当我调试/执行查询时,初始查询运行成功。
我读到,这可能是因为我在表中有现有数据。所以,我改变了这样的逻辑:
再说一次,在某些数据库上它是可以的,而在其他数据库上则不是。试图解决这个问题,我发现了以下几点:
对于 StartDate,我已经指定了当前的 UTC 日期——这可以是未来的任何日期和时间,但请注意它应该是 UTC 日期。如果我尝试使用 GETDATE,因为我目前处于英国夏令时,我会收到以下错误:Msg 13542, Level 16, State 0, Line 51 ADD PERIOD FOR SYSTEM_TIME on table 'TestAudit.dbo.SomeData'失败,因为有打开的记录,期间的开始时间设置为将来的值。
以上是什么意思?我需要更改机器时间吗?还是因为我的本地机器不在 UTC 时间,我有时会收到此错误?
我想我已经找到了解决我的问题的方法,但我不会接受这个作为答案,因为我无法解释导致问题的原因并保证这会在任何时候起作用。这是经过大量测试后找到的修复程序,如果有人能在这里带来更多光明,我会很高兴。
我从来没有datetime2
精确地使用过。所以,我回到了这种格式的来源datetime2(0)
- Alter Non-Temporal Table to be System-Versioned Temporal Table。与我一直使用的脚本的唯一区别是日期时间函数。我使用了GETUTCDATE()
因为我不需要那么精确datetime(0)
(2018-03-15 07:21:02
例如),在这个例子中它是 SYSUTCDATETIME()
. 所以,我已经改变了它。
我已经创建了一个脚本,它会删除数据库(如果存在),从备份中恢复数据库,然后在循环中执行我的代码(正如我所说,我有时会遇到错误并且很难重现它)。
我已经多次运行该脚本,但失败的次数不同(有时为 70%,有时为 50%,有时低于):
我发现了为什么 GETUTCDATE 早于 SYSDATETIMEOFFSET?讨论新旧日期时间函数之间的差异。然后构建以下查询:
DECLARE @UTC DATETIME2(0) = GETUTCDATE();
DECLARE @SYSUTC DATETIME2(0) = SYSUTCDATETIME();
WHILE DATEPART(SECOND, @UTC) = DATEPART(SECOND, @SYSUTC)
BEGIN;
SET @UTC = GETUTCDATE();
SET @SYSUTC = SYSUTCDATETIME();
END;
SELECT @UTC AS [UTC]
,@SYSUTC AS [SYS UTC]
,DATEPART(SECOND, @UTC) AS [UTC sec]
,DATEPART(SECOND, @SYSUTC) AS [SYS UTC sec]
,CASE WHEN @UTC < @SYSUTC THEN 1 ELSE 0 END AS [TimeTravelPossible]
,CONVERT(DATETIME2(0), @UTC) AS [UTC date]
,CONVERT(DATETIME2(0), @SYSUTC) AS [SYS UTC date]
,IIF(CONVERT(DATETIME2(0), @UTC) = CONVERT(DATETIME2(0), @SYSUTC), 1, 0) AS [Are The Same];
Run Code Online (Sandbox Code Playgroud)
我只是想检查是否可以datetime2(0)
使用 sys 而不是 sys 日期时间函数获得不同的日期。当然这是可能的。
也许,引擎正在做的检查正在做这样的事情,将其当前日期与我的较新日期进行比较,这导致了错误 - open records with start of period set to a value in the future.
我已经像这样更改了脚本并在昨晚执行了 1000 次 - 没有生成错误。所以,我相信我已经解决了这个特定问题,但我不能确定。
ALTER TABLE [dbo].[AnalysisCustomRollupsV2JoinGroups]
ADD [SysStartTime] DATETIME2 GENERATED ALWAYS AS ROW START HIDDEN CONSTRAINT DF_AnalysisCustomRollupsV2JoinGroups_SysStart DEFAULT SYSUTCDATETIME()
,[SysEndTime] DATETIME2 GENERATED ALWAYS AS ROW END HIDDEN CONSTRAINT DF_AnalysisCustomRollupsV2JoinGroups_SysEnd DEFAULT CONVERT(DATETIME2, '9999-12-31 23:59:59.9999999'),
PERIOD FOR SYSTEM_TIME ([SysStartTime], [SysEndTime]);
ALTER TABLE [dbo].[AnalysisCustomRollupsV2JoinGroups]
SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.AnalysisCustomRollupsV2JoinGroupsChanges));
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
6845 次 |
最近记录: |