MSSQL GUID/UUID from string



我需要用MSSQL从给定字符串创建永久guid/uuid,但没有找到解决方案。所以这个字符串"A12345"就像"aaaaaaaa - 1234 - 5678 - 90 - ab - aaaaaaaaaaa"每次调用函数时。需要一些建议或例子如何实现。

正如有人在评论中所说,你可能应该重新考虑,但是…如果string的类型为varchar(16)或更小(不是nvarchar),则有一种方法至少可以近似地实现我所理解的您的目标。

我不太了解你的情况,不能推荐这个解决方案,但是假设你确实需要这样做…至少,这可以帮助您构建自己的函数,或者决定这是一个坏主意。下面的解决方案要求您构建另一个函数,如果您希望返回原始值,则在检索数据时基本上反向执行相同的操作。

唯一标识符可视地由0-9和A- f之间的32个字母数字字符以及4个破折号组成的字符串表示。这意味着字符串中的每个位置有16个选项,总共有32个位置。我不建议在这个函数中使用字母A作为填充符,下面我使用0代替,因为00在ASCII中是NULL,而AA将代表一个实际的字符。

开始,您可以使用ASCII()函数将字符串中的每个字符转换为其ASCII值。然后,您可以通过对该值使用除法和模数16将返回的整数转换为十六进制字符串表示形式。在SQL Server中,ASCII的范围从0到255,这意味着有256个不同的字符。256是16乘以16,这意味着你需要在唯一标识符中的两个位置来表示输入字符串中的每个字符,因此这个函数中最大16个字符串的限制而不是32个(参见前面的段落)。最后,您需要在正确的位置插入破折号,并将字符串转换为唯一标识符。

CREATE FUNCTION dbo.MYGUID (@input varchar(17))
RETURNS uniqueidentifier
BEGIN
/* Unable to convert any string langer than 16 characters with this method */
IF LEN(@input) > 16
RETURN CAST('FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF' as uniqueidentifier)

DECLARE 
@result varchar(36) = '',
@char char(1) = '',
@placeholder varchar(32) = REPLICATE('0',32)
/* Convert all characters in string to psuedo-hexadecimal */
WHILE LEN(@input) > 0 BEGIN
/* Use first character in input string.. */
SET @char = LEFT(@input, 1)
/* Convert character to hexadecimal representation */
SET @result += CONVERT(char(1),
CASE ASCII(@char) / 16
WHEN 10 THEN 'A'
WHEN 11 THEN 'B'
WHEN 12 THEN 'C'
WHEN 13 THEN 'D'
WHEN 14 THEN 'E'
WHEN 15 THEN 'F'
ELSE CONVERT(char, ASCII(@char) / 16)
END)
+CONVERT(char(1), 
CASE ASCII(@char) % 16
WHEN 10 THEN 'A'
WHEN 11 THEN 'B'
WHEN 12 THEN 'C'
WHEN 13 THEN 'D'
WHEN 14 THEN 'E'
WHEN 15 THEN 'F'
ELSE CONVERT(char, ASCII(@char) % 16)
END
)
/* Remove first character from input string.. */
SET @input = STUFF(@input, 1, 1, '')
END
/* Make sure there are exactly 32 alpha-numeric characters in outgoing string */
SET @result = RIGHT(@placeholder+@result,32)
/* Insert dashes at the correct positions */
SET @result = STUFF(@result, 21, 0, '-')
SET @result = STUFF(@result, 17, 0, '-')
SET @result = STUFF(@result, 13, 0, '-')
SET @result = STUFF(@result, 9, 0, '-')
/* Returns string as uniqueidentifier */
RETURN CAST(@result as uniqueidentifier)
END

创建函数后,可以通过…

使用它。
SELECT dbo.MYGUID(column1)
FROM table1

…或…

SELECT dbo.MYGUID('A12345')

如果你只是想创建一个映射,你可以这样做(示例fiddle):

创建一个表来保存映射

create table StringGuidMap (
Guid uniqueidentifier not null constraint PK_StringGuidMap primary key clustered default NewSequentialId()
, StringId nvarchar(8) not null constraint UK_StringGuidMap_StringId unique
)

创建逻辑以获取映射或根据需要创建新映射:

create procedure sp_GetIdMapping (
@StringId nvarchar(8)
) as
begin
declare @result uniqueidentifier = null
select @result = Guid 
from StringGuidMap 
where StringId = @StringId -- note: case/accent sensitivity depends on your DB's collation
if (@result is null)
begin

insert into StringGuidMap(StringId) 
values (@StringId)

select @result = Guid 
from StringGuidMap 
where StringId = @StringId

end
select @result Guid
end

在上面的示例中,我使用NewSequentialId生成GUID,以确保该列可以很容易地用作索引中的主键/而不会造成碎片,因为生成的每个新ID将放在现有索引的末尾。但是,如果您愿意/可以在存储过程中生成GUID,而不是在插入中作为默认值生成GUID,那么您可以使用newid()来生成GUID,从而减少对存储过程的调用。你用哪个取决于你的需求

注意:以上是一个映射;但这种映射只对有映射表的人有意义/这不是普遍正确的;所以,这是否合适取决于你的要求。

这是一个ms sql函数来创建uuid v3和v5:https://gist.github.com/osexpert/3cc0aee7817e4d492d5915acb34708c1你发送一个uuid作为'namespace'和一个字符串,然后取回一个uuid。Uuid v3和v5是从随机字符串创建Uuid的标准方法,但它并不为人所熟知。使用标准方式的好处是你创建了真正的uid,并且它们被设计成不会与其他真正的uid冲突。

最新更新