Use RAND() in User Defined Function

后端 未结 5 982
青春惊慌失措
青春惊慌失措 2020-12-06 06:10

I am trying to create a user defined function which calls the system RAND() function inside it, when I try to create the function it errors out with the followi

5条回答
  •  無奈伤痛
    2020-12-06 06:46

    be carefull with RAND!

    If you check this, you'll see, that multiple calls to this VIEW come all back with the same value. This is different with NEWID(). So if you really want random numbers it could be better to take NEWID() und do some "tricks" to get a number from - let's say - the first bytes...

    CREATE VIEW vw_getRANDValue
    AS
    SELECT RAND() AS Value
    GO
    CREATE VIEW vw_getNEWID
    AS
    SELECT NEWID() AS Value
    GO
    CREATE FUNCTION dbo.Test() 
    RETURNS TABLE AS
    RETURN
    WITH Numbers AS
    (SELECT 1 AS x UNION SELECT 2 UNION SELECT 3) 
    SELECT *
         ,(SELECT Value FROM vw_getRANDValue) AS myRandom
         ,(SELECT Value FROM vw_getNEWID) AS myNewid
    FROM Numbers
    GO
    SELECT * FROM dbo.Test();
    GO
    DROP FUNCTION dbo.Test;
    GO
    DROP VIEW vw_getRANDValue;
    GO
    DROP VIEW  vw_getNEWID;
    GO      
    

    This is a result:

    1. 0,684530884058892 D1809581-BBD1-4D23-A7F9-BC697E869BB0
    2. 0,684530884058892 A4BAECDE-E993-46C1-B571-7440A713C371
    3. 0,684530884058892 D7A1CB65-D2BC-41B2-990D-C3BC52B056A2

    A view for a random BIGINT could look like this:

    CREATE VIEW vw_getRandomBigInt
    AS
    SELECT CONVERT(BIGINT,CONVERT(VARBINARY(16),NEWID(),1)) * (-1) AS Value
    GO
    

    Hint: I checked this with many rows and it seems (just by sight), that this approach is not really random (all BIGINTs have the same width...). This seems to work properly:

    CREATE VIEW vw_getRandomInt
    AS
    SELECT sys.fn_replvarbintoint(sys.fn_cdc_hexstrtobin(LEFT(REPLACE(CONVERT(VARCHAR(100),NEWID()),'-',''),4))) AS Value
    GO
    

提交回复
热议问题