我写一个程序,其中每个调用它需要获得一个随机数。 这个过程是从我们的.NET Web服务调用。
我试图实现这种使用兰特()。 然而,当我必须在几毫秒内存储过程的多个调用,我得到了很多的碰撞在产生相同随机数。 如果有后续调用之间大约20或30毫秒的空间,它似乎工作确定。
看来,兰特()补种通过SqlServer的每个存储过程调用。 据我了解,这是一个问题,因为一个人应该一次播种随机数生成器,如果一个补种每次调用兰特一个没有得到伪随机数的好序。 此外,似乎在同一SP在1个或2毫秒调用get接种相同的值。
这是在存储过程中的语句本身。
DECLARE @randomNumber char(9)
SET @randomNumber = RIGHT('00000' + CAST(CAST(rand()*100000 AS INT) AS VARCHAR(5)),5)
+ RIGHT('00000' + CAST(CAST(rand()*10000 AS INT) AS VARCHAR(4)),4)
有没有人有解决这个建议?
我将不得不写接种一次,在整个电话表保存其状态我自己的随机数发生器? SQL Server如何种子兰特()? 它是完全随机的,或者如果你调用内互相单独连接的1或2毫秒的SP将它使用相同的种子发生碰撞接种?
如果您在使用SQL Server 2008,那么你可以使用CRYPT_GEN_RANDOM()函数。 这将随机数据的每一行,即使你试图计算出数以百万计的随机数在一个查询执行,并没有任何问题,播种:
SELECT CAST(RIGHT(CAST(CAST(CRYPT_GEN_RANDOM(1) AS INT) AS VARCHAR(100)), 1) AS INT)
这里的链接到BOL文章:
http://msdn.microsoft.com/en-us/library/cc627408.aspx
在你的榜样,代替rand()*10000
与ABS(CHECKSUM(NEWID())) % 9999
然而,对于char(9):
SELECT RIGHT('000000000' + CAST(ABS(CHECKSUM(NEWID()) % 999999999) AS char(9), 9)
种子RAND 随机 ...
RAND(CHECKSUM(NEWID()))
编辑:
注意,RAND被严重在SQL Server中实现。 不要使用它。
你可以使用一个表只是一个标识符字段创建独特nunbers作为种子使用方法:
declare
@randomNumber char(9),
@seed1 int,
@seed2 int
insert into SeedTable () values ()
set @seed1 = scope_identity()
insert into SeedTable () values ()
set @seed2 = scope_identity()
set @randomNumber = right('00000' +
cast(cast(rand(@seed1) * 100000 as int) as varchar(5)), 5) +
right('00000' +
cast(cast(rand(@seed2) * 10000 as int) as varchar(4)), 4)
if (@seed2 > 10000) truncate table SeedTable
该RAND()函数有,你可以使用这个可选的种子参数。 如果你通过了最后生成的随机值作为种子到兰特()的下一次调用,可以保证得到一个新的随机数。
由于GBN用于指出所述种子是一个整数,而RAND()返回float。 有了这些知识,这里有一个工作的例子! 首先创建一个表:
create table RandomNumber (number float)
insert into RandomNumber values (rand())
然后抓住一个随机数,并存储在一个事务中新的电话号码:
declare @new float
begin transaction
select @new = rand(-2147483648 + 4294967295 * number)
from RandomNumber with (updlock, holdlock)
update RandomNumber set number = @new
commit transaction
print 'Next bingo number is: ' + cast(cast(@new*100 as int) as varchar)
一个SQL Server的整数-2147483648到2147483647之间变化,并且随机数为0.0和1.0之间的浮动。 所以-2147483648 + 4294967295 * number
应覆盖全部可用整数。
该交易可确保只有一次一个连接读取并存储一个新号码。 所以数字是随机的,甚至到SQL Server的不同连接。 (顺便说一句,我投GBN的回答,似乎要容易得多。)