【问题标题】:Using crypt_gen_random to generate unique Serial Numbers使用 crypt_gen_random 生成唯一的序列号
【发布时间】:2020-03-10 06:53:30
【问题描述】:

尝试生成具有字母数字(A-Z、a-z、0-9)且没有特殊字符的唯一序列号。在代码下方使用,其中 sLength 为最小 10 和最大 12,如前端定义的那样。

declare @sLength tinyint
declare @randomString varchar(50)
declare @counter tinyint
declare @nextChar char(1)
declare @rnd as float

set @sLength = 3
set @counter = 1
set @randomString = ''

while @counter <= @sLength
begin
    -- crypt_gen_random produces a random number. We need a random    
    -- float.
    select @rnd = cast(cast(cast(crypt_gen_random(2) AS int) AS float) /    
         65535  as float)  
    select @nextChar = char(48 + convert(int, (122-48+1) * @rnd))
    if ascii(@nextChar) not in (58,59,60,61,62,63,64,91,92,93,94,95,96)
    begin
        select @randomString = @randomString + @nextChar
        set @counter = @counter + 1
    end
 end
 select @randomString

现在要求已经改变,我们将发送在前端选择的字符集(最少 6 分钟)和数字(最少 2 分钟)。所以我将发送参数如下@Include = 'ABCDEFG12345' 和@Exclude='HIJKLMNOPQRSTUVXYZ06789'。有人可以建议我如何根据要求更改以下代码。

我的想法是更改 if ascii(@nextChar) not in 行并添加 @Exclude 字符和数字的所有 Ascii 代码,但无法编写相同的代码。

【问题讨论】:

  • 考虑在客户端执行此操作。 T-SQL 只是一种非常糟糕的语言来做这种事情。此外,还不清楚为什么你需要 both @Include@Exclude - 提供这些还不够吗只有@Include?如果意图是 @Include 包含以某种方式强制的字符,则需要更精确的规范(并且 T-SQL 对这种逻辑的吸引力变得更小了)。

标签: sql sql-server sql-server-2008


【解决方案1】:

我已修改代码以插入唯一的序列号,如下所示。

declare @i int = 4000
while @i>0  
begin
declare @sLength tinyint
declare @randomString varchar(50)
declare @counter tinyint
declare @nextChar char(1)
declare @rnd as float
declare @ExcludeNumbers varchar(50)
DECLARE @XML XML
set @ExcludeNumbers='A,B,C,D,E,F,G,H,1,2,3'
SET @XML = CAST('<i>' + REPLACE(@ExcludeNumbers, ',', '</i><i>') + '</i>' AS XML)

set @sLength = 10
set @counter = 1
set @randomString = ''

while @counter <= @sLength
begin
    -- crypt_gen_random produces a random number. We need a random
        -- float.
    select @rnd = cast(cast(cast(crypt_gen_random(2) AS int) AS float) /    
         65535  as float)  
    select @nextChar = char(48 + convert(int, (122-48+1) * @rnd))
    if ascii(@nextChar)   in (select ASCII((x.i.value('.', 'VARCHAR(MAX)'))) FROM  @XML.nodes('i') x(i))
    begin
        select @randomString = @randomString + @nextChar
        set @counter = @counter + 1
    end
 end
 insert into serialNo values( @randomString);   
 select @i = @i-1 
 End

【讨论】:

    最近更新 更多