有没有办法从时间戳类型列中获取DateTime值?

时间:2008-10-07 11:06:45

标签: sql sql-server tsql

我需要一个select from table,它没有列表示插入行的时间,只有timestamp列(值如:0x0000000000530278)。昨天有些数据被导入到表中,现在我需要找出确切导入的内容:(

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

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

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

8 个答案:

答案 0 :(得分:19)

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

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

答案是:

答案 1 :(得分:9)

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

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

要获得新行或更新行的所需内容,您应该可以添加另一个datetime列(lastupdate)和一个触发器,以便在每次更新时更新该列。

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

答案 2 :(得分:4)

我担心将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恢复算法。

答案 3 :(得分:3)

你的另一个答案是:

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

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

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

0x00000000000007D1
0x00000000000007D2
0x00000000000007D3
0x00000000000007D4
0x00000000000007D5

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

答案 4 :(得分:1)

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

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

答案 5 :(得分:0)

我认为最好的办法是在插入之前恢复备份,并将备份表与当前表进行比较。

答案 6 :(得分:0)

要按时间戳标识新行,您需要预先跟踪那里的时间戳。在紧要关头,你可以:

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

如果在DB中发生任何其他事情,那么误报的风险很小,这将给你一个相当不错的差异。

对于更强大的检查,您可以在行内容上计算带有Hashbytes的MD5或SHA-1哈希值,以便在碰撞概率非常低的情况下给出差异(请参阅Birthday attacks上的这篇维基百科文章讨论这个问题)。

答案 7 :(得分:0)

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

时间戳/ RowVersion可以投放到BigInt,但无论如何都无法与日期时间进行比较。

以下声明摘自MSDN

  

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

有关详细信息,请参阅here