복붙노트

[SQL] 왜 RAND ()는 난수를 생성되지 않는 이유는 무엇입니까?

SQL

왜 RAND ()는 난수를 생성되지 않는 이유는 무엇입니까?

나는 질문이 근방에 응답하고 게시하기 전에 약간의 쿼리를 테스트하지만, 이상한 결과가 나왔어요 내 SSMS를 발사했다. 다음 쿼리는 다음과 같습니다

UPDATE Person
SET   Pos_X = Rand()
    , Pos_Y = Rand(id)

SELECT ID, Surname, Forename, Pos_X, Pos_Y FROM Person

그리고 현재 결과 집합은 다음과 같습니다

1   Bloggs  Fred    0.332720913214171   0.713591993212924
2   Doe     Jane    0.332720913214171   0.713610626184182
3   Smith   Mary    0.332720913214171   0.71362925915544
4   Jones   Martha  0.332720913214171   0.713647892126698
5   Jones   Martha  0.332720913214171   0.713666525097956
6   Jones   Martha  0.332720913214171   0.713685158069215
7   Jones   Martha  0.332720913214171   0.713703791040473
8   Jones   Martha  0.332720913214171   0.713722424011731
9   Jones   Martha  0.332720913214171   0.713741056982989

씨앗은 각 행에서 같은 결과를 넣어없이 나는 랜드를 예상하지만 서로의 0.0002 내에서 더 나은 정렬 된 목록보다 약간 할 것 (albiet 단지 숫자 1 ~ 9) 씨앗과 그 랜드를 기대했다으로!

동일한를받을 수 있나요? 조심성을 잡을 수있는 일 같은이 소리.

난으로 확인이 관련이있을 것이다 :

@@Version = 'Microsoft SQL Server 2005 - 9.00.5000.00 (Intel X86)   Dec 10 2010 10:56:29   Copyright (c) 1988-2005 Microsoft Corporation  Express Edition on Windows NT 6.1 (Build 7601: Service Pack 1)  '

해결법

  1. ==============================

    1.RAND (SQL 트랜잭션) :

    RAND (SQL 트랜잭션) :

    과:

    (강조 광산)

  2. ==============================

    2.당신은 항상 임의의 숫자를 원하는 제공 아래 쿼리로 시도시겠습니까.

    당신은 항상 임의의 숫자를 원하는 제공 아래 쿼리로 시도시겠습니까.

    SELECT RAND(CAST(RIGHT(CAST(CAST(CRYPT_GEN_RANDOM(4) 
                             AS INT) AS VARCHAR(100)), 1) AS INT))
    

    업데이트 : 대화에 따르면, 나는 아래로 내 대답을 변경했습니다 :

    SELECT CAST(CRYPT_GEN_RANDOM(4) AS INT)
    
  3. ==============================

    3.엘리야의 대답에 CRYPT_GEN_RANDOM 기능, 더 나은 솔루션 작업 저를 얻었다 :

    엘리야의 대답에 CRYPT_GEN_RANDOM 기능, 더 나은 솔루션 작업 저를 얻었다 :

    CREATE FUNCTION dbo.MyRAND(@Seed as bigint) RETURNS float(53) AS
    BEGIN
        --Sample: SELECT dbo.MyRAND(DEFAULT), dbo.MyRAND(DEFAULT), dbo.MyRAND(12345) FROM ( SELECT 1 AS ID UNION SELECT 2 UNION SELECT 3 ) as ThreeRows
        DECLARE @Return as float(53)
        IF @Seed = 0
            SET @Return = (Cast(CRYPT_GEN_RANDOM(8) as bigint) + POWER(Cast(2 as float(53)), 63)) / POWER(2.0, 64)
        ELSE 
            SET @Return = (Cast(CRYPT_GEN_RANDOM(8, CAST(@Seed AS varbinary(8))) as bigint) + POWER(Cast(2 as float(53)), 63)) / POWER(2.0, 64)
        RETURN @Return
    END
    

    이 때문에, 시드를 사용하지 않는 곳에서 떨어질 수 있어야 RAND로서 0과 1 사이의 동일한 플로트 ()를 생성한다. 샘플에 의해 입증 된 바와 같이 또한 당 행으로 호출됩니다. 그러나 RAND는 달리 동일한 결과를 생성하지 않습니다 같은 종자를 사용.

    노트

    이것은 더 이상 작동하지 않습니다 :

    Select @@Version 
        Microsoft SQL Server 2014 - 12.0.4100.1 (Intel X86) 
        Apr 20 2015 17:34:37 
        Copyright (c) Microsoft Corporation
        Developer Edition on Windows NT 6.1 <X64> (Build 7601: ) (WOW64)
    

    같이

    Msg 443, Level 16, State 1, Procedure MyRAND, Line 10
    Invalid use of a side-effecting operator 'Crypt_Gen_Random' within a function.
    
  4. ==============================

    4.랜드 () 각 행마다 개별적으로 호출이 이렇게되었는지 확인합니다 :

    랜드 () 각 행마다 개별적으로 호출이 이렇게되었는지 확인합니다 :

    create view wrapped_rand_view
    as
        select rand( ) as random_value
    go
    
    create function wrapped_rand()
    returns float as
    begin
        declare @f float
        set @f = (select random_value from wrapped_rand_view)
        return @f
    end
    
    select 
        ThreeRows.ID, dbo.wrapped_rand() wrapped_rand
    from 
        ( SELECT 1 AS ID UNION SELECT 2 UNION SELECT 3 ) as ThreeRows
    
  5. from https://stackoverflow.com/questions/8378587/why-is-rand-not-producing-random-numbers by cc-by-sa and MIT license