我有一个CreateDate datetime
字段default(getdate())
的表格,其中没有任何标识列。
我想添加identity(1,1)
字段,该字段将反映现有记录的相同顺序,因为CreateDate
字段(order by
会产生相同的结果)。我怎么能这样做?
我想如果我在CreateDate
字段上创建聚簇密钥然后添加标识列它将起作用(不确定它是否有保证),是否有更好/更好的方法?
我对SQL Server 2005感兴趣,但我想SQL Server 2008,SQL Server 2000的答案是相同的。
答案 0 :(得分:8)
继Remus'理论答案之后...你需要先按照理想的顺序生成一个列表
SELECT
ID, CreateDate
INTO
MyNewTable
FROM
(
SELECT
CreateDate,
ROW_NUMBER() OVER (ORDER BY CreateDate ASC) AS ID
FROM
MyTable
) foo
然后,最好的解决方案是使用SSMS将IDENTITY属性添加到MyNewTable。 SSMS将生成一个包含SET IDENTITY INSERT的脚本以保留订单
注意:IDENTITY列只是没有隐含含义的数字,在本练习之后,它们与CreateDate的对齐不能推断出任何内容......
答案 1 :(得分:4)
在SQL 2012中使用序列号而不是标识列。 http://msdn.microsoft.com/en-us/library/ff878058.aspx
答案 2 :(得分:2)
IDENTITY值通常与物理存储顺序正交。特别是,由于日期时间分辨率为3毫秒,允许多行具有相同的日期时间,因此身份不会始终与日期时间群集密钥顺序匹配。此外,如果原始时间绑定到客户端计算机(即中间层,asp层,用户计算机等),那么计算机之间的时间漂移也将确保插入顺序(IDENTITY将给出的)与存储顺序之间的差异。
如果需要行顺序整数,请在投影列表中使用ROW_NUMBER()。如果您需要用于ORM目的的IDENTITY主键,请使用IDENTITY列并将其索引为非聚集索引。
永远不要将物理存储要求(群集密钥)与逻辑建模要求(主键)混淆。
答案 3 :(得分:1)
正如您所怀疑的那样,它会根据聚集索引添加它们。否则,你必须从某个地方的代码中完成它。