我需要创建一个包含简短指南的专栏。所以我发现了这样的事情:
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))
但我仍然遇到同样的错误。
不存在“简短指南”之类的东西。 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)
请记住,在这种情况下,不能保证该指南是唯一的。
使用
CRYPT_GEN_RANDOM
代替 NEWID
可以改善字符串的随机分布。
SELECT LEFT(CAST(CAST(CRYPT_GEN_RANDOM(16) AS UNIQUEIDENTIFIER) AS VARCHAR(50)), 6)
我刚刚做了这个,因为我在互联网上找不到好的答案。
请记住,这是 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
我阅读了所有答案并使用“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()