2008-10-07 117 views
11

我需要一个从表中选择的列,它没有列告知何时行被插入,只有timestamp列(值如:0x0000000000530278)。 ?一些数据导入到表昨天,现在我需要找出究竟是进口:(有没有办法从时间戳类型列中获取日期时间值?

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

  • 时间戳是一个8个字节顺序六角数,也无关既没有日期也没有时间
  • 要获得时间戳的当前值,使用:@@ DBTS

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

回答

19

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

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

答案是:没有

9

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

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

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

对于过去已插入的行,我不认为您可以做一些事情来找到确切的时间。

+0

解释了timestamp列的类型,但未回答我的问题: – Dandikas 2008-10-07 11:11:52

0

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

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恢复算法。

+0

也许有一种方法可以找到特定时间周围的时间戳值?导入是一个后面的事情,所以时间差距很大(不需要精确度) – Dandikas 2008-10-07 11:40:51

3

另一个回答你的问题:

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

时间戳仅仅是被增量是在包含时间戳列一个表来执行每个插入或更新操作的计数器的值。

如果数据导入所发生昨天的几条记录一个插入,你可能会看到数字的序列中的时间戳列象例如:

0x00000000000007D1 
0x00000000000007D2 
0x00000000000007D3 
0x00000000000007D4 
0x00000000000007D5 

最新的时序可以让您的数据(当然它不是guarantied) 如果你使用它们),以确定您所感兴趣的记录您CON结合了其他的东西,知识(如自动增量列。

0

要通过时间戳确定新行,你需要保持跟踪预先在那里的时间戳。在一个捏你可以:

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

如果在数据库中发生了其他任何事情,就会有小的误报风险,这会给您带来相当不错的区别。

对于一个更强大的检查,你可以计算MD5或SHA-1散列与Hashbytes对行的内容,为您带来碰撞的概率非常低的差异(见这个问题的讨论Birthday attacks这个维基百科文章) 。

0

我知道这太晚了,但可能会帮助别人。

时间戳/ RowVersion可以输出到BigInt,但无论如何它不能与日期时间进行比较。

下面的语句从MSDN

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

有关更多详细信息请参考here

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 
相关问题