【问题标题】:Is there a way to get DateTime value from timestamp type column?有没有办法从时间戳类型列中获取 DateTime 值?
【发布时间】:2008-10-07 11:06:44
【问题描述】:

我需要一个从表中选择,它没有告诉何时插入行的列,只有 timestamp 列(值如:0x0000000000530278)。昨天有些数据被导入到表中,现在我需要找出究竟导入了什么:(

有没有办法只使用timestamp 信息? Here我发现:

  • 时间戳是一个 8 字节的连续十六进制数,与日期和时间无关。
  • 要获取时间戳的当前值,请使用:@@DBTS。

也许有一种方法可以在特定时间找到timestamp 的值?这将有助于形成一个选择。或者也许有一个众所周知的解决方案?

【问题讨论】:

    标签: sql sql-server tsql


    【解决方案1】:

    Transact-SQL 时间戳数据类型是一种二进制数据类型,没有与时间相关的值。

    所以回答你的问题:有没有办法从时间戳类型列中获取 DateTime 值?

    答案是:没有

    【讨论】:

      【解决方案2】:

      SQL Server 2005 中的 timestamp 数据类型是 rowversion 的同义词,只是一个随着每次行更新自动递增的数字。

      您可以将其转换为 bigint 以查看其值。

      要获得您想要的新行或更新行,您应该适当地添加另一个日期时间列 (lastupdate) 和一个触发器,以在每次更新时更新该列。

      对于过去已经插入的行,我认为您无法找到确切的时间。

      【讨论】:

      • 这解释了时间戳列类型,但没有回答我的问题:|
      【解决方案3】:

      恐怕无法将 TIMESTAMP 转换/转换为 DATETIME。 它们有完全不同的用途和不兼容的实现。

      查看此链接 http://www.sqlteam.com/article/timestamps-vs-datetime-data-types

      网上书也说http://msdn.microsoft.com/en-us/library/aa260631.aspx

      SQL Server 时间戳数据类型具有 与时间或日期无关。 SQL 服务器时间戳是二进制数 表示相对顺序 哪些数据修改发生在 一个数据库。时间戳数据类型 最初是为了支持 SQL Server 恢复算法。

      【讨论】:

      • 也许有办法找到特定时间的时间戳值?导入是后事,所以时间差距很大(不需要精度)
      【解决方案4】:

      你问题的另一个答案:

      如果时间戳列是您恢复的唯一资源(无备份等),您可以尝试使用以下逻辑

      Timestamp 只是一个计数器的值,每次对包含时间戳列的表执行插入或更新操作时,该计数器都会递增

      如果昨天发生的数据导入是多条记录的插入,您可能会在时间戳列中看到一系列数字,例如:

      0x00000000000007D1
      0x00000000000007D2
      0x00000000000007D3
      0x00000000000007D4
      0x00000000000007D5
      

      最近的序列可以是你添加的数据(当然不保证) 您可以将该知识与其他事物(例如,如果您使用自动增量列)结合起来,以识别您感兴趣的记录。

      【讨论】:

        【解决方案5】:

        其他人正确指出时间戳是二进制计数器。 然而,如果在您的数据库的任何表中,您有时间戳和记录它的日期时间,您可以使用该信息从任何时间戳转到日期范围。 日志表是一个很好的候选者。假设您的导入表是“发票”,您可以使用如下查询:

        WITH TS 
        AS
        (
        SELECT 
            L1.LastDateUpdated, COALESCE(L2.LastDateUpdated, {TS '2099-12-31 00:00:00'}) as LastDateUpdatedTo,
            L1.[TIMESTAMP], L2.[TIMESTAMP] as [TIMESTAMPTo]
        FROM 
        (
            SELECT L1.[LastDateUpdated]
                  ,L1.[TIMESTAMP]
                  ,ROW_NUMBER() OVER (ORDER BY L1.[LastDateUpdated]) ID
            FROM [Log] L1
        ) L1
        left join 
        (
            SELECT L2.[LastDateUpdated]
                  ,L2.[TIMESTAMP]
                  ,ROW_NUMBER() OVER (ORDER BY L2.[LastDateUpdated]) ID
            FROM [Log] L2
        ) L2 
            ON L1.ID = L2.ID - 1
        )
        SELECT TS.LastDateUpdated, TS.LastDateUpdatedTo, * from [Invoices]
            inner join TS ON [Invoices].Timestamp between TS.Timestamp and 
        TS.TIMESTAMPTo
        ORDER BY TS.TIMESTAMPTo DESC
        

        【讨论】:

          【解决方案6】:

          我认为您最好的选择是从插入之前恢复备份并将备份的表与当前表进行比较。

          【讨论】:

            【解决方案7】:

            要通过时间戳识别新行,您需要跟踪事先存在的时间戳。在紧要关头,您可以:

            • 在其他地方恢复以前的版本。
            • 将两个表中的数据复制到临时数据库中。
            • 根据其中一个而非另一个中存在的时间戳识别插入的数据。

            如果数据库中发生了其他任何事情,那么误报的风险很小,这将为您带来相当不错的差异。

            要进行更可靠的检查,您可以在行内容上使用 Hashbytes 计算 MD5 或 SHA-1 哈希,从而以非常低的冲突概率为您提供差异(请参阅这篇关于 Birthday attacks 的维基百科文章,以讨论这个问题)。

            【讨论】:

              【解决方案8】:

              我知道为时已晚,但可能会帮助其他人。

              Timestamp/RowVersion 可以转换为 BigInt,但无论如何不能与 datetime 进行比较。

              以下语句取自 MSDN

              Transact-SQL rowversion 数据类型不是日期或时间数据类型。 timestamprowversion 的已弃用同义词。

              更多详情请参考here

              【讨论】:

                猜你喜欢
                • 2022-11-01
                • 2019-09-11
                • 2020-04-10
                • 1970-01-01
                • 2020-01-05
                • 2021-12-27
                • 1970-01-01
                • 1970-01-01
                • 2018-07-20
                相关资源
                最近更新 更多