从SQL生成随机值

时间:2008-11-06 15:41:40

标签: sql sql-server tsql

看起来像大多数其他产品一样,SQL Server随机功能真的不是随机的。所以我们有这个很好的小函数来生成一个10 char值。是否有更好的方法来完成以下操作。我打赌有。

DECLARE @SaltCount INT;
SELECT @SaltCount = COUNT(*) FROM tmp_NewLogin;
PRINT 'Set Salt values for all records' + CAST(@SaltCount AS VARCHAR(10))
DECLARE @CharPool CHAR(83);
DECLARE @Salt VARCHAR(10);
SET @CharPool = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!"#$%&()*+,-./:;<=>?@';

SET NOCOUNT ON;
updateSaltValue:
    SET @Salt = ''
    SELECT @Salt = @Salt + SUBSTRING(@CharPool, number, 1) FROM
    (
    SELECT TOP 10 number FROM MASTER..[spt_values] WHERE TYPE = 'p' AND Number BETWEEN 1 AND 83
    ORDER BY NEWID()
    ) AS t

    UPDATE TOP(1) [table] SET [Salt] = @Salt WHERE [Salt] IS NULL

IF (@@ROWCOUNT > 0)
    GOTO updateSaltValue

SET NOCOUNT OFF;

PRINT 'Completed setting salts for all records';

6 个答案:

答案 0 :(得分:9)

大多数程序员错误地重新发明了随机化功能,并最终得到了一些非随机的东西。我建议你坚持使用内置的RAND()函数。播种一次,然后根据需要获取尽可能多的值。

答案 1 :(得分:3)

重塑兰德是一场灾难。你在哪里注意到它的行为不正确?我认为你甚至不需要种下它。 SQL Server应该自己播种它就好了。当你需要在测试算法或类似算法时多次生成相同的“随机”序列时,才需要播种。

答案 2 :(得分:1)

根据rand()函数的在线书籍:如果未指定seed,则Microsoft SQL Server 2005数据库引擎会随机分配种子值。对于指定的种子值,返回的结果始终相同。
你可以通过快速和快速避免这种情况肮脏的把戏:

  1. 创建如下视图:

    create view [dbo].[wrapped_rand_view]
    as
    select rand( ) as random_value
    
  2. 接下来创建从视图中读取的函数:

    create function [dbo].[wrapped_rand]()
    returns float
    as
    begin
    declare @f float
    set @f = (select random_value from wrapped_rand_view)
    return @f
    
  3. 这样,每次调用wrapped_rand()函数和0到1之间的不同随机值时,都会有随机种子。

答案 3 :(得分:1)

使用Rand()函数....并使用其他随机的方法将其播种,例如当前sysDate中的millesconds数或当前时间戳...或者调用NewId()函数...

答案 4 :(得分:0)

不是您拥有的完整字母随机性,而是随机的:

select substring(replace(newid(),'-',''),0,10)

编辑:我从评论中了解到,newid()对随机性不是很好,特别是与子字符串组合时。

答案 5 :(得分:0)

有时需要使用临时密码重置密码或为新用户生成随机密码。

以下存储过程基于配置结果的四个参数创建随机字符串。

> create proc [dbo].uspRandChars
>     @len int,
>     @min tinyint = 48,
>     @range tinyint = 74,
>     @exclude varchar(50) = '0:;<=>?@O[]`^\/',
>     @output varchar(50) output as 
>     declare @char char
>     set @output = ''
>  
>     while @len > 0 begin
>        select @char = char(round(rand() * @range + @min, 0))
>        if charindex(@char, @exclude) = 0 begin
>            set @output += @char
>            set @len = @len - 1
>        end
>     end