Создание недетерминированных функций в SQL Server с помощью RAND()

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

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

3 ответа

Решение

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

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

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

Использование 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

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

В принципе:

Вместо

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

Другие вопросы по тегам