Детерминированные и недетерминированные функции

Применимо к:SQL ServerБаза данных SQL AzureУправляемый экземпляр SQL AzureКонечная точка аналитики SQL в Microsoft FabricХранилище в Microsoft FabricБаза данных SQL в Microsoft Fabric

Детерминированные функции всегда возвращают один и тот же результат при вызове с определенным набором входных значений и с тем же состоянием базы данных. Недетерминированные функции могут возвращать разные результаты каждый раз, когда они вызываются с определенным набором входных значений, даже если состояние базы данных, к которому они обращаются, остается неизменным. Например, функция AVG всегда возвращает один и тот же результат при соблюдении указанных ранее условий, а функция GETDATE, которая возвращает текущее значение даты и времени, всегда возвращает иной результат.

Существует несколько свойств определяемых пользователем функций, которые определяют, может ли ядро СУБД SQL Server индексировать результаты функции либо с помощью индексов для вычисляемых столбцов, вызывающих эту функцию, либо с помощью индексированных представлений, ссылающихся на нее. Детерминизм функции — одно из таких свойств. Например, кластеризованный индекс нельзя создать в представлении, если представление ссылается на недетерминированные функции. Дополнительные сведения о свойствах функций, включая детерминированность, см. в разделе " Определяемые пользователем функции".

Детерминированные функции должны быть привязаны к схеме. Используйте предложение SCHEMABINDING при создании детерминированной функции.

В этой статье определяется детерминированность встроенных системных функций и влияние на детерминированное свойство определяемых пользователем функций, когда оно содержит вызов расширенных хранимых процедур.

Определение детерминированной функции

Можно проверить, является ли функция детерминированной, запрашивая is_deterministic свойство объекта для функции. В следующем примере определяется, является ли функция Sales.CalculateSalesTax детерминированной.

SELECT OBJECTPROPERTY(OBJECT_ID('Sales.CalculateSalesTax'), 'IsDeterministic');

Детерминированность встроенной функции

Не удается повлиять на детерминированность встроенной функции. Каждая встроенная функция детерминирована или недетерминирована в зависимости от того, как функция реализуется SQL Server. Например, указание ORDER BY предложения в запросе не изменяет детерминированность функции, используемой в этом запросе.

Все встроенные строковые функции являются детерминированными, кроме FORMAT.

Следующие встроенные функции, отличные от строковых функций, всегда детерминированы.

  • ABS
  • ACOS
  • ASIN
  • ATAN
  • ATN2
  • CEILING
  • COALESCE
  • COS
  • COT
  • DATALENGTH
  • DATEADD
  • DATEDIFF
  • DAY
  • DEGREES
  • EXP
  • FLOOR
  • ISNULL
  • ISNUMERIC
  • LOG
  • LOG10
  • MONTH
  • NULLIF
  • POWER
  • RADIANS
  • ROUND
  • SIGN
  • SIN
  • SQRT
  • SQUARE
  • TAN
  • YEAR

Следующие функции не всегда детерминированы, но могут использоваться в индексированных представлениях или индексах для вычисляемых столбцов, когда они указаны детерминированным образом.

Функция Комментарии
Все агрегатные функции Все агрегатные функции являются детерминированными, если только не указано, что они используются с предложениями OVER и ORDER BY. Список этих функций см. в разделе "Агрегатные функции".
CAST Детерминированные, за исключением использования их с данными типа datetime, smalldatetimeи sql_variant.
CONVERT Детерминирована, кроме следующих случаев.

Тип источника — sql_variant.

Конечный тип — sql_variant , и его исходный тип недетерминирован.

Исходный или конечный тип — datetime или smalldatetime, другой исходный или конечный тип — строка символов, и задан недетерминированный стиль. Чтобы быть детерминированным, параметр стиля должен быть константой. Кроме того, стили, которые меньше или равны 100, являются недетерминированными, за исключением стилей 20 и 21. Стили более 100 являются детерминированными, за исключением стилей 106, 107, 109 и 113.
CHECKSUM Детерминированный, за исключением CHECKSUM(*).
ISDATE Детерминированна только при использовании функции CONVERT, если указан параметр стиля CONVERT и значение стиля не равно 0, 100, 9 или 109.
RAND RAND является детерминированным, только если задан начальный параметр.

Все функции конфигурации, курсора, метаданных, безопасности и системные статистические — недетерминированные. Список этих функций можно просмотреть.

Следующие встроенные функции других классов всегда недетерминированы.

  • @@CONNECTIONS
  • @@CPU_BUSY
  • @@DBTS
  • @@IDLE
  • @@IO_BUSY
  • @@MAX_CONNECTIONS
  • @@PACKET_ERRORS
  • @@PACK_RECEIVED
  • @@PACK_SENT
  • @@TIMETICKS
  • @@TOTAL_ERRORS
  • @@TOTAL_READ
  • @@TOTAL_WRITE
  • AT TIME ZONE
  • CUME_DIST
  • CURRENT_TIMESTAMP
  • DENSE_RANK
  • FIRST_VALUE
  • FORMAT
  • GETDATE
  • GETUTCDATE
  • GET_TRANSMISSION_STATUS
  • LAG
  • LAST_VALUE
  • LEAD
  • MIN_ACTIVE_ROWVERSION
  • NEWID
  • NEWSEQUENTIALID
  • NEXT VALUE FOR
  • NTILE
  • PARSENAME
  • PERCENTILE_CONT
  • PERCENTILE_DISC
  • PERCENT_RANK
  • RAND
  • RANK
  • ROW_NUMBER
  • TEXTPTR

Вызов расширенных хранимых процедур из функций

Функции, вызывающие расширенные хранимые процедуры, недетерминированы, так как расширенные хранимые процедуры могут оказать на базу данных побочное действие. Побочные эффекты представляют собой изменения в глобальном состоянии базы данных, например обновление таблицы или внешний ресурс, например файл или сеть. Примеры включают изменение файла или отправку сообщения электронной почты. Не следует полагаться на то, что при выполнении расширенной хранимой процедуры из пользовательской функции будет возвращён согласованный набор результатов. Определяемые пользователем функции, которые создают побочные эффекты в базе данных, не рекомендуется.

При вызове изнутри функции расширенная хранимая процедура не может возвращать результирующие наборы клиенту. Любой API Open Data Services, возвращающий результирующие наборы клиенту, имеет код FAILвозврата.

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

Как и вызовы из пакета или хранимой процедуры, расширенная хранимая процедура выполняется в контексте учетной записи безопасности Windows, в которой выполняется SQL Server. Владелец расширенной хранимой процедуры должен учитывать разрешения в контексте безопасности при предоставлении разрешения на выполнение этой процедуры другим пользователям.