CRYPT_GEN_RANDOM奇怪的效果

one*_*hen 5 sql t-sql sql-server random sql-server-2008

我想从一小部分整数(小于200)中随机选择一个值.作为替代

SELECT RAND()
Run Code Online (Sandbox Code Playgroud)

我正在尝试使用

CAST(CAST(CRYPT_GEN_RANDOM(2) AS INTEGER) AS FLOAT) / 65535
Run Code Online (Sandbox Code Playgroud)

但是我得到了一些奇怪的效果.

例如:

WITH Numbers (num)
     AS
     (
      SELECT num
        FROM (
              VALUES (1), (2), (3), (4), 
                     (5), (6), (7), (8), 
                     (9), (10)
             ) AS Numbers (num)
     ), 
     RandomNumber (num)
     AS 
     (
      SELECT CAST(
                  (CAST(CAST(CRYPT_GEN_RANDOM(2) AS INTEGER) AS FLOAT) / 65535) 
                     * (SELECT COUNT(*) FROM Numbers) + 1 
                  AS INTEGER
                 )
     )
SELECT T1.num, R1.num
  FROM Numbers AS T1 
       INNER JOIN RandomNumber AS R1
          ON T1.num = R1.num;
Run Code Online (Sandbox Code Playgroud)

我希望这会返回一行,两列值相等.

但是,它返回零,一行或多行,列值仅偶尔相等.

知道这里发生了什么吗?

Den*_*eev 8

试试这个:

select abs(checksum(newid()))%200
Run Code Online (Sandbox Code Playgroud)

更新

这里有些可疑的东西:

select 'Not in the range! This is impossible!' [Message]
where cast(CAST(CAST(CRYPT_GEN_RANDOM(2) AS int) AS float) / 65535 * 10  as int) 
not in (0,1,2,3,4,5,6,7,8,9)
Run Code Online (Sandbox Code Playgroud)

点击F5直到收到消息.

更新2

此查询具有相同的效果:

select 'Not in the range! This is impossible!' [Message]
where abs(checksum(newid()))%10
not in (0,1,2,3,4,5,6,7,8,9)
Run Code Online (Sandbox Code Playgroud)

更新3

select N'WTF? Schrödinger''s cat!' [Message], *
from (select 0 union select 1) t(n)
join (select abs(checksum(newid()))%2 rnd) r(n) on t.n = r.n
Run Code Online (Sandbox Code Playgroud)

并且最后一个查询有时可能返回2行,这实际上意味着同时abs(checksum(newid()))%2返回0和1,这是不可能的,因为它包含在"仅选择一行"语句中,因此该值在连接完成后更新.:| 然后再次发生连接,这是令人震惊的.

更新4

这是Microsoft Connect的一个已知错误.下面是一个有见地的文章上正在发生的事情.