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

时间:2016-02-16 10:13:46

标签: sql sql-server triggers sql-server-2012

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

  1. 我们插入一个表来跟踪用户的当前状态,该表有一个触发器,在该触发器上插入用户过去状态的关联历史记录表,其中DATETIME字段和插入调用{{ 1}}

  2. 完成此操作后,我们会在调用GETUTCDATE()时插入另一个带有相关记录的表,该记录会跟踪哪个部分更新了用户状态。

  3. 所以流程将是:

    1. 插入GETUTCDATE()
    2. 触发UserStatuses表插入UserStatusesUserStatusesHistory
    3. 然后我们插入调用GETUTCDATE()
    4. OwningStatuses表格

      我们发现在某些情况下GETUTCDATE()上的DATETIME位于UserStatusesHistory表的DATETIME之后。

      如果在OwningStatuses表的GETUTCDATE()之后调用OwningStatuses上的GETUTCDATE(),该怎么办?

      在某些情况下,触发器是异步运行的吗? (我不能相信这一点,因为它反对我读过的所有内容,而且我们没有使用任何服务代理)。

      在某些情况下,UserStatusesHistory是否可以在程序开始时缓存,并且此缓存值不会被带入触发器?

2 个答案:

答案 0 :(得分:1)

由于SQL的声明性质,数据库引擎可能自由地以它认为合适的任何顺序评估SQL语句的各个部分(只要它不会影响语义) )。您GETUTCDATE()可能被缓存的建议是合理的。

我知道这不能回答你的问题。但无论SQL2012中GETUTCDATE的实现如何,它在未来版本中都可能会发生变化。因此,避免依赖它,或未来的升级可能会成为一个真正的痛苦。以不依赖于评估顺序的任何假设的方式实现您的逻辑。

在您的具体情况下,我会看到一些可能的解决方案。

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

答案 1 :(得分:0)

在呼叫之间调整硬件/ OS时钟。 Happenss。

您需要缓存值 - 您必须首先重新编程所有访问权限以设置变量,然后在后续调用中使用该值;(