我正在尋找一種在TSQL中將唯一標識符增加1的方法。例如,如果ID是A6BC60AD-A4D9-46F4-A7D3-98B2A7237A9E,我希望能夠選擇A6BC60AD-A4D9-46F4-A7D3-98B2A7237A9F。在TSQL中增加唯一標識符
@rein它用於數據導入。我們有一箇中間表,其中包含我們正在生成記錄的ID,並且稍後在導入時加入這些ID。不幸的是,現在這些記錄中的一些在下一個表中生成了一些記錄,所以我們需要一個可重現的新的記錄。
我正在尋找一種在TSQL中將唯一標識符增加1的方法。例如,如果ID是A6BC60AD-A4D9-46F4-A7D3-98B2A7237A9E,我希望能夠選擇A6BC60AD-A4D9-46F4-A7D3-98B2A7237A9F。在TSQL中增加唯一標識符
@rein它用於數據導入。我們有一箇中間表,其中包含我們正在生成記錄的ID,並且稍後在導入時加入這些ID。不幸的是,現在這些記錄中的一些在下一個表中生成了一些記錄,所以我們需要一個可重現的新的記錄。
以下是我想到的一種方法,但我希望有更好的方法。
LEFT([ID], 19) + RIGHT(CONVERT(uniqueidentifier, CONVERT(binary(16), CONVERT(binary(16), [ID]) + CONVERT(bigint, 1))), 17) AS 'MyNewID'
你可以這樣做,但我沒有考慮溢出低8字節的情況。
declare @guid uniqueidentifier, @binaryUpper8 binary(8), @binaryLower8 binary(8), @binary16 binary(16), @bigint bigint
set @guid = 'A6BC60AD-A4D9-46F4-A7D3-98B2A7237A9E'
set @binary16 = cast(@guid as binary(16))
--harvest lower 8 bytes
select @binaryUpper8= substring(0xAD60BCA6D9A4F446A7D398B2A7237A9E, 1, 8)
,@binaryLower8 = substring(0xAD60BCA6D9A4F446A7D398B2A7237A9E, 9, 8)
set @bigint = cast(@binaryLower8 as bigint)
--increment
set @bigint = @bigint + 1
--convert back
set @binaryLower8 = cast(@bigint as binary(8))
set @binary16 = @binaryUpper8 + @binaryLower8
set @guid = cast(@binary16 as uniqueidentifier)
select @guid
要增加GUID是不是爲SQL Server正確的,因爲GUID是在字節組不同字節順序的結構方式,請看看: http://sqlblog.com/blogs/alberto_ferrari/archive/2007/08/31/how-are-guids-sorted-by-sql-server.aspx 並注意以下事項:
現在,當我運行改性Alberto的查詢時,我發現了下列序列: 3,2,1,0,5,4,7,6,9,8,15,14,13,12, 11,10
這意味着,GUID的字節#3是最少的si有意義的和GUID的字節#10是最重要的[從SQL Server ORDER BY子句的角度]。
這裏是簡單的函數來增加一個唯一標識符佔該:
create function [dbo].[IncrementGuid](@guid uniqueidentifier)
returns uniqueidentifier
as
begin
declare @guid_binary binary(16), @b03 binary(4), @b45 binary(2), @b67 binary(2), @b89 binary(2), @bAF binary(6)
select @guid_binary = @guid
select @b03 = convert(binary(4), reverse(substring(@guid_binary,1,4)))
select @b45 = convert(binary(2), reverse(substring(@guid_binary,5,2)))
select @b67 = convert(binary(2), reverse(substring(@guid_binary,7,2)))
select @b89 = convert(binary(2), substring(@guid_binary,9,2))
select @bAF = convert(binary(6), substring(@guid_binary,11,6))
if (@b03 < 'FFFFFFFF')
begin
select @b03 = convert(binary(4), cast(@b03 as int) + 1)
end
else if (@b45 < 'FFFF')
begin
select @b45 = convert(binary(2), cast(@b45 as int) + 1)
end
else if (@b89 < 'FFFF')
begin
select @b89 = convert(binary(2), cast(@b89 as int) + 1)
end
else
begin
select @bAF = convert(binary(6), cast(@bAF as bigint) + 1)
end
return convert(binary(16), reverse(convert(char(4),@b03)) + reverse(convert(char(2),@b45)) + reverse(convert(char(2),@b67)) + convert(char(2),@b89) + convert(char(6),@bAF))
end
注意,字節6和7不遞增,因爲它們含有的GUID版本比特。 但正如其他人指出你真的不應該這樣做。在你的情況下,如果你爲這些Guids創建一個臨時表(有兩列:一個整數作爲索引,第二個具有生成的GUID),可能會更好。
我真的很想知道你爲什麼需要這樣做。 – rein 2009-05-04 22:48:04
如果您發現自己處於需要增加GUID的情況下,10次中有9次我將重新檢查您正在嘗試執行的操作。 – 2009-05-05 03:26:14