如果你想使用 T-SQL 生成一个伪随机字母数字字符串,你会怎么做?您将如何从中排除美元符号、破折号和斜杠等字符? 原文由 Scott Lawrence 发布,翻译遵循 CC BY-SA 4.0 许可协议
在生成随机数据时,特别是为了测试,使数据随机但可重复是非常有用的。秘诀是对随机函数使用显式种子,这样当使用相同的种子再次运行测试时,它会再次产生完全相同的字符串。下面是一个以可重现方式生成对象名称的函数的简化示例: alter procedure usp_generateIdentifier @minLen int = 1 , @maxLen int = 256 , @seed int output , @string varchar(8000) output as begin set nocount on; declare @length int; declare @alpha varchar(8000) , @digit varchar(8000) , @specials varchar(8000) , @first varchar(8000) declare @step bigint = rand(@seed) * 2147483647; select @alpha = 'qwertyuiopasdfghjklzxcvbnm' , @digit = '1234567890' , @specials = '_@# ' select @first = @alpha + '_@'; set @seed = (rand((@seed+@step)%2147483647)*2147483647); select @length = @minLen + rand(@seed) * (@maxLen-@minLen) , @seed = (rand((@seed+@step)%2147483647)*2147483647); declare @dice int; select @dice = rand(@seed) * len(@first), @seed = (rand((@seed+@step)%2147483647)*2147483647); select @string = substring(@first, @dice, 1); while 0 < @length begin select @dice = rand(@seed) * 100 , @seed = (rand((@seed+@step)%2147483647)*2147483647); if (@dice < 10) -- 10% special chars begin select @dice = rand(@seed) * len(@specials)+1 , @seed = (rand((@seed+@step)%2147483647)*2147483647); select @string = @string + substring(@specials, @dice, 1); end else if (@dice < 10+10) -- 10% digits begin select @dice = rand(@seed) * len(@digit)+1 , @seed = (rand((@seed+@step)%2147483647)*2147483647); select @string = @string + substring(@digit, @dice, 1); end else -- rest 80% alpha begin declare @preseed int = @seed; select @dice = rand(@seed) * len(@alpha)+1 , @seed = (rand((@seed+@step)%2147483647)*2147483647); select @string = @string + substring(@alpha, @dice, 1); end select @length = @length - 1; end end go 运行测试时,调用者生成一个随机种子,它与测试运行相关联(将其保存在结果表中),然后传递种子,类似于: declare @seed int; declare @string varchar(256); select @seed = 1234; -- saved start seed exec usp_generateIdentifier @seed = @seed output , @string = @string output; print @string; exec usp_generateIdentifier @seed = @seed output , @string = @string output; print @string; exec usp_generateIdentifier @seed = @seed output , @string = @string output; print @string; 2016-02-17 更新:请参阅下面的评论,原始程序在推进随机种子的方式上存在问题。我更新了代码,还修复了上面提到的问题。 原文由 Remus Rusanu 发布,翻译遵循 CC BY-SA 3.0 许可协议
另一个具有完整字母表的简单解决方案: SELECT LEFT(REPLACE(REPLACE((SELECT CRYPT_GEN_RANDOM(16) FOR XML PATH(''), BINARY BASE64),'+',''),'/',''),16); 将两个 16 替换为所需的长度。 样本结果: pzyMATe3jJwN1XkB 原文由 Tofnet 发布,翻译遵循 CC BY-SA 4.0 许可协议
在生成随机数据时,特别是为了测试,使数据随机但可重复是非常有用的。秘诀是对随机函数使用显式种子,这样当使用相同的种子再次运行测试时,它会再次产生完全相同的字符串。下面是一个以可重现方式生成对象名称的函数的简化示例:
运行测试时,调用者生成一个随机种子,它与测试运行相关联(将其保存在结果表中),然后传递种子,类似于:
2016-02-17 更新:请参阅下面的评论,原始程序在推进随机种子的方式上存在问题。我更新了代码,还修复了上面提到的问题。