Создание недетерминированных функций в SQL Server с помощью RAND () - PullRequest
9 голосов
/ 20 августа 2010

После небольшого поиска и чтения документации становится ясно, что вы можете писать пользовательские функции в SQL Server, которые помечаются как детерминированные или недетерминированные в зависимости от того, какие встроенные функции используются в теле.

RAND () указан в списке недетерминированных функций (см. статья MSDN ).Так почему я не могу использовать его в функции?

Ответы [ 3 ]

19 голосов
/ 20 августа 2010

Использование View может помочь вам.
С Возвращение случайных чисел из оператора выбора

CREATE VIEW vRandNumber
AS
SELECT RAND() as RandNumber

Представление необходимо, потому что, как вы уже узнали, UDF не может использовать функцию rand (), потому что это сделает функцию недетерминированной. Вы можете обмануть UDF, чтобы принять случайное число, используя View.

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

Наконец, вы можете использовать эту функцию в любом SELECT, чтобы теперь возвращать случайное число от 0 до 1 в строке:

SELECT dbo.RandNumber(), *
FROM Northwind..Customers
13 голосов
/ 20 августа 2010

Потому что у него есть побочные эффекты.

Конструкции с побочными эффектами не допускаются в функции.Побочный эффект, который он имеет, заключается в изменении некоторого внутреннего состояния, которое отслеживает последнее выданное значение rand().

Я думаю, что вы можете обойти это, включив его в определение представления, а затем выбрав его из представления.

3 голосов
/ 19 апреля 2016

Я нашел это решение , которое не создает представление:

В основном:

Вместо

SET @R = Rand()

Используйте

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

В моем случае я хотел число от 1 до 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))

Если вы хотите получить полное объяснение: Использование (или имитация) Rand () в пользовательской функции T-Sql

...