2010-09-22 49 views
5

Tôi muốn chọn ngẫu nhiên một giá trị từ một phạm vi nhỏ các số nguyên (nhỏ hơn 200). Để thay thế choCRYPT_GEN_RANDOM hiệu ứng lạ

SELECT RAND() 

Tôi đang cố gắng sử dụng

CAST(CAST(CRYPT_GEN_RANDOM(2) AS INTEGER) AS FLOAT)/65535 

nhưng tôi nhận được một số hiệu ứng lạ.

Ví dụ:

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; 

tôi mong đợi này để trả lại chính xác một hàng với cả hai giá trị cột bằng nhau.

Tuy nhiên, nó trả về 0, một hoặc nhiều hàng, với các giá trị cột chỉ thỉnh thoảng bằng nhau.

Bất kỳ ý tưởng những gì đang xảy ra ở đây?

+0

Đổi tên thành con mèo của Schrödinger hoặc Nguyên tắc không chắc chắn trong Sql Server! hahah –

+0

[Đã viết blog về điều này tại đây] (http://sqlperformance.com/2014/06/t-sql-queries/dirty-secrets-of-the-case-expression). –

Trả lời

8

Hãy thử điều này:

select abs(checksum(newid()))%200 

Cập nhật

Something fishy đang xảy ra ở đây:

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) 

Hit F5 cho đến khi bạn nhận được thông báo.

Cập nhật 2

truy vấn này có tác dụng tương tự:

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) 

Cập nhật 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 

Và truy vấn cuối cùng điều này đôi khi có thể trở lại 2 hàng trong đó chủ yếu có nghĩa là abs(checksum(newid()))%2 trả về 0 và 1 cùng một lúc, đó là impossi ble vì nó được bao gồm trong câu lệnh "select one row only" do đó giá trị được cập nhật sau khi kết nối đã được thực hiện. : | Và sau đó tham gia xảy ra một lần nữa đó là flabbergasting.

Cập nhật 4

Đó là a known bug tại Microsoft Connect. Và đây là an insightful article về những gì đang xảy ra.

+0

Cảm ơn bạn đã thay thế, tôi chắc chắn có nhiều hơn. Nhưng bạn có thể giải thích những hiệu ứng kỳ lạ của mã * của tôi không? – onedaywhen

+0

Có lẽ OP có lý do chính đáng để cần một số ngẫu nhiên có chất lượng mã hóa. – LukeH

+0

@onedaywhen @LukeH Tôi thấy ... –

Các vấn đề liên quan