在存储过程中生成随机字符

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

我正在尝试创建一个存储过程,以从 SQL Server 2016 上的以下字符集随机生成两个唯一的字母数字字符:

ABCDEFGHIJKLMNPQRSTUVWXYZ0123456789
(35 个字符集)。然后,随机值将存储在
AspNetUsers
表的自定义列中。

目前,

AspNetUsers
表中仅存储 132 个唯一的 2 字符值,而总共可以有 1,225 种排列。这是基于排列公式:
n! / (n - r)!
35! / (35 - 2)! = 1225

以下代码基于此示例有时有效,而有时则变成无限循环。外部 WHILE 确保该值在存储它的表中是唯一的。

DECLARE @length int, @charpool varchar(256), @poollength int, 
    @loopcount int, @randomstring varchar(100)
SET @Length = 2

-- define allowable character explicitly - easy to read this way an easy to 
SET @CharPool = 'ABCDEFGHIJKLMNPQRSTUVWXYZ0123456789'
SET @PoolLength = Len(@CharPool)

SET @LoopCount = 0
SET @RandomString = ''

WHILE (SELECT count(*) FROM AspNetUsers anu WHERE anu.CustomId = @randomstring) > 0 BEGIN
    WHILE (@LoopCount < @Length) BEGIN
        SELECT @RandomString = @RandomString + 
            SUBSTRING(@Charpool, CONVERT(int, RAND() * @PoolLength) + 1, 1)
        SELECT @LoopCount = @LoopCount + 1
    END
END
PRINT @randomstring
sql sql-server t-sql stored-procedures
1个回答
0
投票

你可以这样做:

-- Seed existing
DROP TABLE IF EXISTS #aspusers 
CREATE TABLE #aspusers (id int IDENTITY, somerandomValue varchar(2) UNIQUE)

DECLARE @length int, @charpool varchar(256), @poollength int, 
    @loopcount int, @randomstring varchar(100)
SET @Length = 2

-- define allowable character explicitly - easy to read this way an easy to 
SET @CharPool = 'ABCDEFGHIJKLMNPQRSTUVWXYZ0123456789'

;WITH data AS (
    SELECT  TOP(len(@charpool)) row_number() OVER(ORDER BY @@spid) AS rank
        FROM    sys.objects so
    )
INSERT INTO #aspusers (somerandomValue)
SELECT  TOP 132 chrs
FROM    (
    SELECT  substring(@charpool, d.rank, 1) + substring(@charpool, d2.rank, 1) AS chrs
    FROM    data d
    CROSS JOIN data d2
    ) x
ORDER BY NEWID()
-- Generate new random value
;WITH data AS (
    SELECT  TOP(len(@charpool)) row_number() OVER(ORDER BY @@spid) AS rank
        FROM    sys.objects so
    )
SELECT  TOP 1 @randomstring = x.chrs
FROM    data d
CROSS JOIN data d2
CROSS apply (
        SELECT  substring(@charpool, d.rank, 1) + substring(@charpool, d2.rank, 1) AS chrs
    ) x
WHERE   NOT EXISTS(
        SELECT  1
        FROM    #aspusers asp
        WHERE   asp.somerandomValue = x.chrs
    )
ORDER BY NEWID()
-- Output
SELECT  @randomstring, *
FROM    #aspusers

主要思想是生成 1 到 len(charpool) 之间的数字列表,然后使用 SUBSTRING 创建字符组合。

要生成新的随机值,只需添加一个

WHERE NOT EXISTS
来检查原始表。

© www.soinside.com 2019 - 2024. All rights reserved.