Creating Nondeterministic functions in SQL Server using RAND()

后端 未结 3 506
野趣味
野趣味 2020-12-10 15:36

After a bit of searching and reading the documentation, it\'s clear that you can write user defined functions in SQL Server that are marked as either deterministic or nondet

相关标签:
3条回答
  • 2020-12-10 15:51

    Because it has side effects.

    Constructs with side effects are not allowed in a function. The side effect that it has is to change some internal state that keeps track of the last rand() value issued.

    I think you can get around it by including it in a View definition then selecting from the View.

    0 讨论(0)
  • 2020-12-10 15:59

    I found this solution that doesn't create a view:

    Basically:

    Instead of

    SET @R = Rand()
    

    Use

    SET @R = ABS(CHECKSUM(PWDENCRYPT(N''))) / 2147483647.0
    

    In my case I wanted a number between 1 and 10:

    ROUND(((10 - 1 -1) * ( ABS(CHECKSUM(PWDENCRYPT(N''))) / 2147483647.0) + 1), 0))
    
    ROUND(((@max - @lower -1) * ( ABS(CHECKSUM(PWDENCRYPT(N''))) / 2147483647.0) + @lower), 0))
    

    If you want a full explanation: Using (Or Simulating) Rand() In A T-Sql User-Defined Function

    0 讨论(0)
  • 2020-12-10 16:04

    Using a View might work for you.
    From Returning Random Numbers from a select statement

    CREATE VIEW vRandNumber
    AS
    SELECT RAND() as RandNumber
    

    The view is necessary because, as you already found out, a UDF cannot use the rand() function because that would make the function non-determistic. You can trick the UDF to accept a random number by using a View.

    CREATE FUNCTION RandNumber()
    RETURNS float
    AS
      BEGIN
      RETURN (SELECT RandNumber FROM vRandNumber)
      END
    

    Finally, you can use this function in any SELECT to now return a random number between 0 and 1 per row:

    SELECT dbo.RandNumber(), *
    FROM Northwind..Customers
    
    0 讨论(0)
提交回复
热议问题