2010-09-22 10 views
5

मैं यादृच्छिक रूप से पूर्णांक की एक छोटी श्रृंखला (200 से कम) से एक मान चुनना चाहता हूं।CRYPT_GEN_RANDOM अजीब प्रभाव

SELECT RAND() 

के लिए एक विकल्प के रूप में मैं

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

उपयोग करने के लिए कोशिश कर रहा हूँ, लेकिन मैं कुछ अजीब प्रभाव हो रही है।

उदाहरण के लिए:

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; 

मैं इस बराबर दोनों स्तंभ मान के साथ वास्तव में एक पंक्ति वापस जाने के लिए उम्मीद थी।

हालांकि, यह शून्य, एक या अधिक पंक्तियां देता है, कॉलम मान केवल कभी-कभी बराबर होते हैं।

कोई विचार क्या हो रहा है?

+0

इसे एसक्यूएल सर्वर में श्रोडिंगर की बिल्ली या अनिश्चितता सिद्धांत के रूप में नामित करें! हाहा –

+0

[यहां इस बारे में ब्लॉग किया गया है] (http://sqlperformance.com/2014/06/t-sql-queries/dirty-secrets-of-the-case-expression)। –

उत्तर

8

इस प्रयास करें:

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

अद्यतन

कुछ गड़बड़ यहाँ पर जा रहा है:

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) 

मारो 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) 

अद्यतन 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 

और यह पिछले क्वेरी कभी कभी 2 पंक्तियाँ जो अनिवार्य रूप से इसका मतलब है कि वापस आ सकते हैं abs(checksum(newid()))%2 एक ही समय में 0 और 1 देता है जो impossi है खून के रूप में इसे "केवल एक पंक्ति का चयन करें" कथन में शामिल किया गया है, इसलिए शामिल होने के बाद मूल्य अपडेट हो जाता है। : | और फिर जुड़ना फिर से होता है जो flabbergasting है।

अद्यतन 4

यह माइक्रोसॉफ्ट कनेक्ट पर a known bug है। और यहां क्या हो रहा है पर an insightful article है।

+0

वैकल्पिक के लिए धन्यवाद, मुझे यकीन है कि और भी कुछ हैं। लेकिन क्या आप * मेरे * कोड के अजीब प्रभावों को समझा सकते हैं? – onedaywhen

+0

शायद ओपी के पास क्रिप्टो-गुणवत्ता यादृच्छिक संख्या की आवश्यकता के लिए एक अच्छा कारण है। – LukeH

+0

@onedaywhen @LukeH मैं देखता हूं ... –

संबंधित मुद्दे