我的想法是在SQL服务器中为我的表生成一个唯一的ID Alphanumeric for My table所以我使用Newid函数来执行此操作,然后将结果截断为8个字符。我的问题是这个代码我肯定有一个唯一的ID?或者可能不是这里的代码:
DECLARE @r varchar(8)
SELECT @r = coalesce(@r, '') + n
FROM (SELECT top 8 CHAR(number) n
FROM master..spt_values
WHERE type = 'P' AND
(number between ascii(0) and ascii(9)
OR number between ascii('A') and ascii('Z')
OR number between ascii('a') and ascii('z'))
ORDER BY newid()) a
DECLARE @id varchar(10)
SET @id=CONVERT(varchar(8), @r)
DECLARE @myid varchar(10)
SELECT @myid=SUBSTRING(@r,1,2)+'-'+SUBSTRING(@r,3,3)+'-'+SUBSTRING(@r,6,3)
PRINT 'Value of @myid is: '+ @myid
答案 0 :(得分:4)
NEWID()生成v4 GUID。在该GUID方案中,前8个字节可以是任何十六进制数字0-F,并且将完全由随机生成的数据组成。这不能保证是独一无二的;实际上没有保证v4 GUID是唯一的,只是随机位(128个中的112个)可以代表5.19 十亿个数字中的一个,因此它们中的任何两个匹配在同一系统中的几率是无穷小的。只有前8个字节,你将只有2 ^ 32个组合,这可能看起来仍然很多(四十亿分之一)但是由于生日问题,在生成了少量77,000之后你有50-50个镜头在生成副本。
答案 1 :(得分:1)
我认为这是一个坏主意,你一次插入多行并保持唯一值会有问题。但是,只是为了好玩,这里有一些代码来增加一个包含8个字母数字字符的字符串(假设值应该从0-9开始,然后是A-Z):
DECLARE @s varchar(20)= '00-0Z-0Z-ZZ'; --INPUT
DECLARE @n char(36) = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
DECLARE @pos tinyint;
SET @s = REPLACE(@s,'-',''); --REMOVE DASHES
SET @pos = LEN(@s);
WHILE @pos > 0
BEGIN
IF SUBSTRING(@s,@pos,1) = 'Z'
BEGIN
SET @s = STUFF(@s,@pos,1,'0');
SET @pos = @pos - 1;
END
ELSE
BEGIN
SET @s = STUFF(@s,@pos,1,SUBSTRING(@n,
CHARINDEX(SUBSTRING(@s,@pos,1),@n)+1,1))
SET @pos = 0
END
END
SET @s = SUBSTRING(@s,1,2) + '-'
+ SUBSTRING(@s,3,2) + '-'
+ SUBSTRING(@s,5,2) + '-'
+ SUBSTRING(@s,7,2) -- Replace Dashes
SELECT @s --OUTPUT
答案 2 :(得分:0)
如果我理解正确,SQL服务器的NewId会生成GUID (Globally unique identifier),这是一个128位的值,通常表示为32个字符的十六进制字符串。
有限,它肯定不能保证唯一性,因为只有 2 ^ 128个可能的值。但这是一个足够大的空间,碰撞很少见。
如果你把它截断为8个字符(我假设你的意思是十六进制表示中的8个字符),你可以大大减少唯一性的可能性,因为有2 ^ 32个可能的值。
当然不能保证唯一性。
答案 3 :(得分:0)
create or replace FUNCTION "GEN1_9A_Z" ( start_val varchar2)
return varchar2
-----------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------
-- GEN1_9A_Z generate next unique alphanumeric string with size 3 -- (0..9A..Z) --
-- Return 0 when error or end (ZZZ). --
-----------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------
-- 001,002,..,009,00A,00B,..,00Z,
-- 010,011,..,019,01A,01B,..,01Z,
-- .............................
-- 090,091,..,099,09A,09B,..,09Z,
-- 0A0,0A1,.................,0AZ,
-- 0B0,0B1,.................,0BZ,
-- .............................
-- 0Z0,0Z1,.................,0ZZ,
-- 100,101,.................,10Z,
-- 110,111,.................,11Z,
-- .............................
-- 990,991,.................,99Z,
-- 9A0,9A1,.................,9AZ,
-- .............................
-- 9Z0,9Z1,.................,9ZZ,
-- A00,A01,.................,A0Z,
-- A10,A11,.................,A1Z,
-- .............................
-- A90,A91,.................,A9Z,
-- AA0,AA1,.................,AAZ,
-- AB0,AB1,.................,ABZ,
-- ..............................
-- AZ0,AZ1,.................,AZZ,
-- B00,B01,.................,B0Z,
-- ..............................
-- ..............................
-- ZZ0,ZZ1,.................,ZZZ ---- END!!!
------------------------- generate 46656 unique alphanumeric. ( 000 - ZZZ ) --------------------------------
-----------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------
is
start_value varchar2(3);
return_val varchar2(3);
begin
if length(start_val) <= 3 then
start_value := lpad(upper(start_val),3,'0');
select
(case
when p1= 0 and p2 = 0 and p3 = 0 and v3 != '9' then lpad(to_char(start_value+1),3,'0')
when p1= 0 and p2 = 0 and p3 = 0 and v3 = '9' then v1||v2||chr(65)
when p1= 0 and p2 = 0 and p3 = 1 and ASCII(v3) between 65 and 89 then v1||v2||chr(ASCII(v3)+1)
when p1= 0 and p2 = 0 and p3 = 1 and v2 != '9' and v3 = 'Z' then v1||chr(ASCII(v2)+1)||'0'
when p1= 0 and p2 = 0 and p3 = 1 and v2 = '9' and v3 = 'Z' then v1||chr(65)||'0'
when p1= 0 and p2 = 1 and p3 = 0 and v3 != '9' then v1||v2||chr(ASCII(v3)+1)
when p1= 0 and p2 = 1 and p3 = 0 and v3 = '9' then v1||v2||chr(65)
when p1= 0 and p2 = 1 and p3 = 1 and v3 != 'Z' then v1||v2||chr(ASCII(v3)+1)
when p1= 0 and p2 = 1 and p3 = 1 and ASCII(v2) between 65 and 89 and v3 = 'Z' then v1||chr(ASCII(v2)+1)||'0'
when p1= 0 and p2 = 1 and p3 = 1 and v1 != '9' and v2 = 'Z' and v3 = 'Z' then chr(ASCII(v1)+1)||'0'||'0'
when p1= 0 and p2 = 1 and p3 = 1 and v1 = '9' and v2 = 'Z' and v3 = 'Z' then chr(65)||'00'
when p1= 1 and p2 = 0 and p3 = 0 and v3 != '9' then v1||v2||chr(ASCII(v3)+1)
when p1= 1 and p2 = 0 and p3 = 0 and v3 = '9' then v1||v2||chr(65)
when p1= 1 and p2 = 0 and p3 = 1 and v3 != 'Z' then v1||v2||chr(ASCII(v3)+1)
when p1= 1 and p2 = 0 and p3 = 1 and v2 != '9' and v3 = 'Z' then v1||chr(ASCII(v2)+1)||'0'
when p1= 1 and p2 = 0 and p3 = 1 and v2 = '9' and v3 = 'Z' then v1||chr(65)||'0'
when p1= 1 and p2 = 1 and p3 = 0 and v3 != '9' then v1||v2||chr(ASCII(v3)+1)
when p1= 1 and p2 = 1 and p3 = 0 and v3 = '9' then v1||v2||chr(65)
when p1= 1 and p2 = 1 and p3 = 1 and v3 != 'Z' then v1||v2||chr(ASCII(v3)+1)
when p1= 1 and p2 = 1 and p3 = 1 and v2 != 'Z' and v3 = 'Z' then v1||chr(ASCII(v2)+1)||'0'
when p1= 1 and p2 = 1 and p3 = 1 and v1 != 'Z' and v2 = 'Z' and v3 = 'Z' then chr(ASCII(v1)+1)||'00'
else '0'
end)
into return_val
from
(
select
NVL(LENGTH(TRIM(TRANSLATE(substr(start_value,1,1), ' +-.0123456789',' '))),0) p1,
NVL(LENGTH(TRIM(TRANSLATE(substr(start_value,2,1), ' +-.0123456789',' '))),0) p2,
NVL(LENGTH(TRIM(TRANSLATE(substr(start_value,3,1), ' +-.0123456789',' '))),0) p3,
NVL(substr(start_value,1,1),0) v1,
NVL(substr(start_value,2,1),0) v2,
NVL(substr(start_value,3,1),0) v3,
start_value
from dual
);
else
return_val := '0';
end if;
return return_val;
end;