生成一个范围内的随机数、字母或字符

Generate random numbers, letters or characters within a range

我正在为 SQL 服务器进行数据匿名化。

我有这 3 个公式可以帮助我创造我想要的东西:

SELECT CHAR(cast((90 - 65) * rand() + 65 AS INTEGER)) -- only letters
SELECT CAST((128 - 48) * RAND() + 48 AS INTEGER) -- only numbers
SELECT CHAR(CAST((128 - 48) * RAND() + 48 AS INTEGER)) -- letters, numbers, symbols

但是,这只能创建1 个数字1 个字母1 个符号

我想要自由地创建随机字符串或我想要的长度的数字。比如3或5个数字3或5个字母3或5个数字、字母或符号之间 .

我也找到了一些非常接近我想要的东西:

SELECT LEFT(CAST(NEWID() AS VARCHAR(100)), 3) -- letters and numbers 

这是一个非常聪明的想法,因为使用 NEWID() 并且它允许我创建一个随机的数字和字母序列,其长度为我想要的(在本例中为 3)。但是缺少符号。

我需要 3 个不同的 SELECT:

可以自由选择数据的长度。

完整的解决方案需要完成一些工作,但如果您仍然需要的话,这里是您可能想进一步试验的想法的工作原理:

declare @type varchar(10)='letters', @length tinyint=5;

with chars as (
    select top(59) 31 + Row_Number() over (order by (select 1)) n from master.dbo.spt_values
), s  as (
    select top (@length) Char(n.n) c
    from chars n
    where @type='all' 
    or (@type='symbols' and n between 33 and 47)
    or (@type='numbers' and n between 48 and 57)
    or (@type='letters' and n between 65 and 90)
    order by newid()
)
select String_Agg(s.c,'') 
from s

递归查询可能适用于 rand() 函数:

declare @desiredlength tinyint=5;

With builder As (
    Select *
    From (Values (0, '', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')) initial (length, randstr, pool)
  Union All
    Select length+1, randstr + substring(pool,cast(rand()*len(pool)+1 AS int),1), pool
    From builder
    Where length<@desiredlength
)
Select randstr From builder
Where length=@desiredlength

rand() 在单个select returns 中每行一个select 相同的随机数。但是在递归 select 中,您处于灰色区域,每个递归都可能被视为单独的查询。

显然,您可以将池定义定制为您想要的任何字符集,其余代码将从那里选择任何字符集。