我需要为MS Sql表创建一个View(没有Id),新的View必须包含一个UNIQUE 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
答案 0 :(得分: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添加到 end :
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。
答案 1 :(得分:2)
您可以使用NEWID()
投影随机新GUID。显然,虽然投射随机guid 不与投射行标识符(主键)相同。实际上,如果表没有数据库强制主键,则基本上无法来投影正确的主键值。 任何努力都会因并发和更新(特别是删除)而无效。。
答案 2 :(得分: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的完整HEX表示合并到guid中。
如果EventId是唯一的且永远不会更改某一行,则新的EventId总是大于所有现有的(例如IDENTITY值),您永远不会删除一行,并且所有插入都使用表锁,这将为每一行创建相同的值时间。如果没有给出上述任何一项,解决此问题的唯一方法是向表中添加一个guid列,除非您不关心连续运行之间的值是否发生变化。