SQL Server 2012:DATETIME插入和触发器之间的差异

ciste 发布于 2019-08-14 sql 最后更新 2019-08-14 08:39 2 浏览

我们遇到一个非常奇怪的问题,即在调用GETUTCDATE()时,第二个语句中的返回值比第一个语句稍早。我们的情景如下:

  1. 我们插入到表中以跟踪用户当前状态,此表具有一个触发器,通过DATETIME字段和插入调用GETUTCDATE()
  2. 插入到用户历史记录表的相关历史记录表中,
  3. 完成此操作后,我们将另一个表格与我们插入的关联记录插入调用GETUTCDATE(),该表格跟踪哪部分更新了用户状态。
所以流程将是:
  1. 插入UserStatuses
  2. 触发UserStatuses表格插入到UserStatusesHistory调用GETUTCDATE()
  3. 然后我们插入OwningStatuses表中调用GETUTCDATE()
我们发现在某些情况下,UserStatusesHistory上的DATETIME位于OwningStatuses表格上的DATETIME之后。 在OwningStatuses表格的GETUTCDATE()之后调用PLACEHOLDER_FOR_CODE_15上的GETUTCDATE()时,该情况如何? 在某些情况下,触发器是异步运行的吗? (我无法相信这是因为它违背了我读过的所有内容,而且我们没有使用任何服务代理)。 在某些情况下,GETUTCDATE()是否可能在过程的开始处被缓存,并且这个缓存的值不会被带入触发器?
已邀请:

yut

赞同来自:

在呼叫之间调整硬件/ OS时钟。 Happenss。 您需要缓存的值 - 您必须首先重新编程所有访问权限以设置变量,然后在后续调用中使用该值;(

sed_et

赞同来自:

由于SQL的声明性,数据库引擎可以自由地以它认为合适的任何顺序评估SQL语句的各个部分(只要它不影响语义)。您对GETUTCDATE()可能被缓存的建议是合理的。 我知道这不能回答你的问题。但无论SQL2012中GETUTCDATE的实现如何,它在未来版本中都可能会发生变化。因此,避免依赖它,或未来的升级可能会成为一个真正的痛苦。以不依赖于评估顺序的任何假设的方式实现您的逻辑。 在您的具体情况下,我看到了一些可能的解决方案。

  1. 如果您对OwningStatuses的时间稍晚于UserStatusesHistory没有任何问题,那么如果您将第三步作为单独的批处理发送到SQL Server,则可能会有所帮助。
  2. 交换步骤2和3;并让触发器查询OwningStatuses,而不是自己编造日期。
  3. 停止使用触发器;不止一个理由要考虑这一点。