如何在SQL Server中创建唯一的随机字母数字序列

时间:2015-04-20 11:21:45

标签: sql-server

我想将唯一的随机字母数字序列作为数据库表的主键。

序列中的每个字符都是字母(a-z)或数字(0-9)

我想要的例子:

kl7jd6fgw
zjba3s0tr
a9dkfdue3

我想创建一个可以处理该任务的函数!

4 个答案:

答案 0 :(得分:2)

您可以使用uniqueidentifier。这可以使用NEWID()函数生成:

SELECT NEWID()

会返回类似的内容:

BE228C22-C18A-4B4A-9AD5-1232462F7BA9

答案 1 :(得分:1)

使用随机字符串作为主键是一个非常的坏主意。
它会影响性能和存储大小,并且使用带有标识属性的int或bigint会更好。

然而,在SQL中生成随机字符串可能对其他事情有用,这就是我提供此解决方案的原因:

创建一个表来保存允许的char值 在我的例子中,允许的字符是0-9和A-Z。

CREATE TABLE Chars (C char(1))

DECLARE @i as int = 0
WHILE @i < 10
BEGIN
  INSERT INTO Chars (C) VALUES (CAST(@i as Char(1)))
  SET @i = @i+1
END

SET @i = 65
WHILE @i < 91
BEGIN
  INSERT INTO Chars (C) VALUES (CHAR(@i))
  SET @i = @i+1
END

然后使用这个简单的select语句从该表生成一个随机字符串:

SELECT TOP 10 C AS [text()]
FROM Chars
ORDER BY NEWID()
FOR XML PATH('')

优点:

  • 您可以轻松控制允许的字符。
  • 生成新字符串是一个简单的select语句,而不是对字符串的操作。

缺点:

  • 此选择结果带有丑陋的名称(即XML_F52E2B61-18A1-11d1-B105-00805F49916B)。通过将结果设置为局部变量,可以轻松解决此问题。

  • 字符只会在每个字符串中出现一次。这可以通过添加union来轻松解决:

示例:

SELECT TOP 10 C AS [text()]
  FROM (
    SELECT * FROM Chars
    UNION ALL SELECT * FROM Chars
  ) InnerSelect
  ORDER BY NEWID()
  FOR XML PATH('')

另一种选择是使用STUFF函数而不是As [Text()]来消除那些讨厌的XML标记:

SELECT STUFF((
 SELECT TOP 100 ''+ C 
 FROM Chars
 ORDER BY NEWID()
 FOR XML PATH('')
), 1, 1, '') As RandomString;

此选项没有丑陋的列名称的缺点,并且可以直接使用别名。执行计划略有不同,但不应该遭受很多性能损失。

Play with it yourself in this Sql Fiddle

如果您有任何其他优点/缺点,请发表评论。感谢。

答案 2 :(得分:0)

NewID()函数将生成唯一的数字。所以我用循环递增它们并使用Charindex和Left函数拾取字母数字字符的组合

;with list as 
    (
        select 1 as id,newid() as val
             union all
        select id + 1,NEWID()
        from    list   
        where   id + 1 < 100
    ) 
    select ID,left(val, charindex('-', val) - 2) from list
    option (maxrecursion 0)

答案 3 :(得分:0)

此请求的NEWID()缺点是它将字符池限制为0-9和A-F。要定义自己的角色池,您必须为自定义解决方案发挥作用。

此解决方案改编自Generating random strings with T-SQL

--Define list of characters to use in random string
DECLARE @CharPool VARCHAR(255)
SET @CharPool = '0123456789abcdefghijkmnopqrstuvwxyz'

--Store length of CharPool for use later
DECLARE @PoolLength TINYINT
SET @PoolLength = LEN(@CharPool) --36

--Define random string length
DECLARE @StringLength TINYINT
SET @StringLength = 9

--Declare target parameter for random string
DECLARE @RandomString VARCHAR(255)
SET @RandomString = ''

--Loop control variable
DECLARE @LoopCount TINYINT
SET @LoopCount = 0

--For each char in string, choose random char from char pool
WHILE(@LoopCount < @StringLength)
BEGIN
    SELECT @RandomString += SUBSTRING(@Charpool, CONVERT(int, RAND() * @PoolLength), 1)
    SELECT @LoopCount += 1
END

SELECT @RandomString

http://sqlfiddle.com/#!6/9eecb/4354

但是,我必须重申,我同意其他人的观点:这是一个可怕的想法。