SQL Server 中的短 guid / 从字符串转换为唯一标识符

问题描述 投票:0回答:4

我需要创建一个包含简短指南的专栏。所以我发现了这样的事情:

alter table [dbo].[Table]
add InC UNIQUEIDENTIFIER not null default LEFT(NEWID(),6)

但是我收到错误:

从字符串转换为uniqueidentifier时转换失败。

我一直在努力

LEFT(CONVERT(varchar(36),NEWID()),6)

CONVERT(UNIQUEIDENTIFIER,LEFT(CONVERT(varchar(36),NEWID()),6))

但我仍然遇到同样的错误。

sql-server guid
4个回答
4
投票

不存在“简短指南”之类的东西。 Guid,或

uniqueidentifier
是 16 字节数据类型。您可以在 MSDN 中阅读相关内容。这意味着长度必须始终为 16 个字节,并且您不能像您尝试的那样使用 6 个字符。

在同一篇 MSDN 文章中,您可以找到如何初始化此类型的描述:

uniqueidentifier 数据类型的列或局部变量可以是 通过以下方式初始化为一个值:

  • 通过使用NEWID函数。
  • 通过从 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 形式的字符串常量进行转换,其中每个 x 是一个
    0-9 或 a-f 范围内的十六进制数字。例如,
    6F9619FF-8B86-D011-B42D-00C04FC964FF 是有效的唯一标识符
    值。

在您的情况下,您尝试仅将 6 个字符转换为

uniqueidentifier
,这显然失败了。

如果您只想使用 6 个字符,只需使用

varchar(6)
:

alter table [dbo].[Table]
add InC varchar(6) not null default LEFT(NEWID(),6)

请记住,在这种情况下,不能保证该指南是唯一的。


2
投票

使用

CRYPT_GEN_RANDOM
代替
NEWID
可以改善字符串的随机分布。

SELECT LEFT(CAST(CAST(CRYPT_GEN_RANDOM(16) AS UNIQUEIDENTIFIER) AS VARCHAR(50)), 6)


1
投票

我刚刚做了这个,因为我在互联网上找不到好的答案。

请记住,这是 128 位值的 64 位表示,因此它的冲突可能性是真实 GUID 的两倍。不处理 0。

函数采用 NEWID 值:6A10A273-4561-40D8-8D36-4D3B37E4A19C

并将其缩短为:7341xIlZseT

DECLARE @myid uniqueidentifier= NEWID()
select @myid
DECLARE @bigintdata BIGINT = cast(cast(reverse(NEWID()) as varbinary(max)) as bigint)
DECLARE @charSet VARCHAR(70) = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
DECLARE @cBase int = LEN(@charSet)
DECLARE @sUID varchar(22) = ''
DECLARE @x int

WHILE (@bigintdata <> 0)
BEGIN 
    SET @x = CAST(@bigintdata % @cBase as INT) + 1
    SET @bigintdata = @bigintdata / @cBase
    SET @sUID = SUBSTRING(@charSet, @x, 1) + @sUID;
END

SELECT @sUID

0
投票

我阅读了所有答案并使用“CrimsonMoose”的答案来解决我的问题。 修改他们的代码并使其可用后,我想出了以下代码:

CREATE OR ALTER VIEW GUIDView AS SELECT [GUID]=NEWID()
GO
CREATE OR ALTER FUNCTION dbo.CreateCompressedGUID()
RETURNS VARCHAR(11)
BEGIN
    DECLARE @result         VARCHAR(22) = '';
    DECLARE @keyGUID        BIGINT;
    DECLARE @resultChars    VARCHAR(70) = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    DECLARE @division       INT = LEN(@resultChars)
    DECLARE @divisionRemained int;
    SELECT @keyGUID=CAST(CAST(REVERSE([GUID]) AS VARBINARY(MAX)) AS BIGINT) FROM GUIDView

    WHILE (@keyGUID <> 0)
    BEGIN 
        SET @divisionRemained = @keyGUID % @division;
        SET @divisionRemained = @divisionRemained + 1;
        SET @keyGUID = @keyGUID / @division;
        SET @result = SUBSTRING(@resultChars,@divisionRemained,1) + @result;
    END;

    RETURN @result;
END;
GO
SELECT Example = dbo.CreateCompressedGUID()
© www.soinside.com 2019 - 2024. All rights reserved.