1

我需要为 MS Sql 表(没有 ID)创建一个视图,新视图必须包含一个唯一的 ID。目前我正在使用 ROW 编号和stuff函数来创建一个 Id。

不幸的是,有一张大桌子,结果是一些重复的 ID。

我相信问题可能在于'72799568-6EF2-4C95-84E7-4953A6959C90'我如何解决它?

CREATE VIEW viewWithId as
SELECT convert(uniqueidentifier,
       stuff('72799568-6EF2-4C95-84E7-4953A6959C90',1,len(rn),convert(varchar,rn))) [Id],
       T.[EventId], 
       T.[EventTitle]
FROM 
    ( 
        select  x.[EventId], 
                x.[EventTitle]
                ROW_NUMBER() over (order by x.EventId) rn
        FROM    dbo.A as x 
    ) T
4

3 回答 3

3

出现重复的原因是因为第 1、12 和 127 行(通常是第 n、10*n+2 和 100*n+27 行)都返回相同的标识符。如果你需要一个GUID然后使用

CREATE VIEW viewWithId as
SELECT NEWID() [Id],
       T.[EventId], 
       T.[EventTitle]
FROM 
    ( 
        select  x.[EventId], 
                x.[EventTitle]
                ROW_NUMBER() over (order by x.EventId) rn
        FROM    dbo.A as x 
    ) T

然而,问题是当您重新选择视图时,您会为每一行获得不同的 UUID。

如果您尝试从 Id 中“生成”一个 GUID,您将必须想出一个保证对于任何 Id 都是唯一的算法。另一种选择是从 0 开始并将 Id 添加到末尾

SELECT convert(uniqueidentifier,
           stuff('72799568-6EF2-4C95-84E7-000000000000',
                 36-LEN(rn),
                 len(rn),
                 convert(varchar,rn)
                )
            ) [Id],
       T.[EventId], 
       T.[EventTitle]
FROM 
    ( 
        select  x.[EventId], 
                x.[EventTitle]
                ROW_NUMBER() over (order by x.EventId) rn
        FROM    dbo.A as x 
    ) T

这将为 999,999,999,999(约 1 万亿)行提供足够的“唯一”ID。

于 2013-03-11T13:37:49.587 回答
2

您可以使用NEWID()投影一个随机的新 GUID。显然,虽然投影随机 guid投影行标识符(主键)不同。事实上,如果表没有数据库强制主键,则基本上没有办法投影正确的主键值。在并发和更新(特别是删除)的情况下,任何努力都是徒劳的

于 2013-03-11T13:39:58.323 回答
1

如果您希望 guid 依赖于 eventid,请使用以下代码:

CREATE VIEW viewWithId as
SELECT convert(uniqueidentifier,
       '72799568-6EF2-4C95-'
        + STUFF(CONVERT(VARCHAR(36), CAST(rn AS VARBINARY(8)), 2),5, 0, '-')
       ) [Id],
       T.[EventId], 
       T.[EventTitle]
FROM 
    ( 
        select  x.[EventId], 
                x.[EventTitle],
                ROW_NUMBER() over (order by x.EventId) rn
        FROM    dbo.A as x 
    ) T

它将 ROW_NUMBER 的完整十六进制表示合并到 guid 中。

如果 EventId 是唯一的并且永远不会更改一行,那么新的 EventId 总是大于所有现有的(例如 IDENTITY 值),您永远不会删除一行并且所有插入都使用表锁,这将每次为每一行创建相同的值。如果没有给出上述任何一项,解决此问题的唯一方法是向表中添加一个 guid 列,除非您不关心连续运行之间的值是否发生变化。

于 2013-03-11T13:46:26.927 回答