我正在编写一个程序,每次调用它需要一个随机数.从我们的.net Web服务调用此过程.
我尝试使用rand()实现这一点.但是,当我在几毫秒内对存储过程进行多次调用时,我发生了很多冲突,因为生成了相同的随机数.如果在后续呼叫之间有大约20或30毫秒的空间,它似乎工作正常.
看来rand()重新被SqlServer重新调用每个存储过程调用.从我的理解这是一个问题,因为一个应该播种一个随机数生成器,如果一个重播每次调用rand,那个没有得到一个好的伪随机数序列.此外,看起来对在1或2毫秒内的相同sp的调用获得相同的值.
这是存储过程中的语句本身.
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)
Run Code Online (Sandbox Code Playgroud)
有没有人有解决这个问题的建议?
我是否必须编写自己的随机数生成器,该生成器一次播种并将其状态保存在跨调用的表中?SQL Server种子rand()如何?它是真正随机的还是如果你在一个连接上在一个或两个毫秒内调用一个sp,它会在同一个种子上播种导致冲突吗?
如果您使用的是SQL Server 2008,则可以使用CRYPT_GEN_RANDOM()函数.即使您尝试在一次查询执行中计算数百万个随机数并且没有任何种子问题,这将随机化每行的数据:
SELECT CAST(RIGHT(CAST(CAST(CRYPT_GEN_RANDOM(1) AS INT) AS VARCHAR(100)), 1) AS INT)
Run Code Online (Sandbox Code Playgroud)
这是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)
Run Code Online (Sandbox Code Playgroud)
随机播种兰德......
RAND(CHECKSUM(NEWID()))
Run Code Online (Sandbox Code Playgroud)
编辑:
注意,RAND在SQL Server中实现得很糟糕.不要使用它.
| 归档时间: |
|
| 查看次数: |
4918 次 |
| 最近记录: |